Bug Summary

File:build/source/clang/lib/Sema/SemaOpenMP.cpp
Warning:line 8420, column 51
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -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/source/build-llvm -resource-dir /usr/lib/llvm-16/lib/clang/16 -I tools/clang/lib/Sema -I /build/source/clang/lib/Sema -I /build/source/clang/include -I tools/clang/include -I include -I /build/source/llvm/include -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -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-16/lib/clang/16/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/source/build-llvm=build-llvm -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm=build-llvm -fcoverage-prefix-map=/build/source/= -source-date-epoch 1671487667 -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 -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -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-12-20-010714-16201-1 -x c++ /build/source/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_private = 1 << 2, /// Default data sharing attribute 'private'.
63 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
64};
65
66/// Stack for tracking declarations used in OpenMP directives and
67/// clauses and their data-sharing attributes.
68class DSAStackTy {
69public:
70 struct DSAVarData {
71 OpenMPDirectiveKind DKind = OMPD_unknown;
72 OpenMPClauseKind CKind = OMPC_unknown;
73 unsigned Modifier = 0;
74 const Expr *RefExpr = nullptr;
75 DeclRefExpr *PrivateCopy = nullptr;
76 SourceLocation ImplicitDSALoc;
77 bool AppliedToPointee = false;
78 DSAVarData() = default;
79 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
80 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
81 SourceLocation ImplicitDSALoc, unsigned Modifier,
82 bool AppliedToPointee)
83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
85 AppliedToPointee(AppliedToPointee) {}
86 };
87 using OperatorOffsetTy =
88 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
89 using DoacrossDependMapTy =
90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
91 /// Kind of the declaration used in the uses_allocators clauses.
92 enum class UsesAllocatorsDeclKind {
93 /// Predefined allocator
94 PredefinedAllocator,
95 /// User-defined allocator
96 UserDefinedAllocator,
97 /// The declaration that represent allocator trait
98 AllocatorTrait,
99 };
100
101private:
102 struct DSAInfo {
103 OpenMPClauseKind Attributes = OMPC_unknown;
104 unsigned Modifier = 0;
105 /// Pointer to a reference expression and a flag which shows that the
106 /// variable is marked as lastprivate(true) or not (false).
107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
108 DeclRefExpr *PrivateCopy = nullptr;
109 /// true if the attribute is applied to the pointee, not the variable
110 /// itself.
111 bool AppliedToPointee = false;
112 };
113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
115 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
116 using LoopControlVariablesMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
118 /// Struct that associates a component with the clause kind where they are
119 /// found.
120 struct MappedExprComponentTy {
121 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
122 OpenMPClauseKind Kind = OMPC_unknown;
123 };
124 using MappedExprComponentsTy =
125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
126 using CriticalsWithHintsTy =
127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
128 struct ReductionData {
129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
130 SourceRange ReductionRange;
131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
132 ReductionData() = default;
133 void set(BinaryOperatorKind BO, SourceRange RR) {
134 ReductionRange = RR;
135 ReductionOp = BO;
136 }
137 void set(const Expr *RefExpr, SourceRange RR) {
138 ReductionRange = RR;
139 ReductionOp = RefExpr;
140 }
141 };
142 using DeclReductionMapTy =
143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
144 struct DefaultmapInfo {
145 OpenMPDefaultmapClauseModifier ImplicitBehavior =
146 OMPC_DEFAULTMAP_MODIFIER_unknown;
147 SourceLocation SLoc;
148 DefaultmapInfo() = default;
149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
150 : ImplicitBehavior(M), SLoc(Loc) {}
151 };
152
153 struct SharingMapTy {
154 DeclSAMapTy SharingMap;
155 DeclReductionMapTy ReductionMap;
156 UsedRefMapTy AlignedMap;
157 UsedRefMapTy NontemporalMap;
158 MappedExprComponentsTy MappedExprComponents;
159 LoopControlVariablesMapTy LCVMap;
160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
161 SourceLocation DefaultAttrLoc;
162 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
163 OpenMPDirectiveKind Directive = OMPD_unknown;
164 DeclarationNameInfo DirectiveName;
165 Scope *CurScope = nullptr;
166 DeclContext *Context = nullptr;
167 SourceLocation ConstructLoc;
168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
169 /// get the data (loop counters etc.) about enclosing loop-based construct.
170 /// This data is required during codegen.
171 DoacrossDependMapTy DoacrossDepends;
172 /// First argument (Expr *) contains optional argument of the
173 /// 'ordered' clause, the second one is true if the regions has 'ordered'
174 /// clause, false otherwise.
175 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
176 bool RegionHasOrderConcurrent = false;
177 unsigned AssociatedLoops = 1;
178 bool HasMutipleLoops = false;
179 const Decl *PossiblyLoopCounter = nullptr;
180 bool NowaitRegion = false;
181 bool UntiedRegion = false;
182 bool CancelRegion = false;
183 bool LoopStart = false;
184 bool BodyComplete = false;
185 SourceLocation PrevScanLocation;
186 SourceLocation PrevOrderedLocation;
187 SourceLocation InnerTeamsRegionLoc;
188 /// Reference to the taskgroup task_reduction reference expression.
189 Expr *TaskgroupReductionRef = nullptr;
190 llvm::DenseSet<QualType> MappedClassesQualTypes;
191 SmallVector<Expr *, 4> InnerUsedAllocators;
192 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
193 /// List of globals marked as declare target link in this target region
194 /// (isOpenMPTargetExecutionDirective(Directive) == true).
195 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
196 /// List of decls used in inclusive/exclusive clauses of the scan directive.
197 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
198 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
199 UsesAllocatorsDecls;
200 /// Data is required on creating capture fields for implicit
201 /// default first|private clause.
202 struct ImplicitDefaultFDInfoTy {
203 /// Field decl.
204 const FieldDecl *FD = nullptr;
205 /// Nesting stack level
206 size_t StackLevel = 0;
207 /// Capture variable decl.
208 VarDecl *VD = nullptr;
209 ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
210 VarDecl *VD)
211 : FD(FD), StackLevel(StackLevel), VD(VD) {}
212 };
213 /// List of captured fields
214 llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
215 ImplicitDefaultFirstprivateFDs;
216 Expr *DeclareMapperVar = nullptr;
217 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
218 Scope *CurScope, SourceLocation Loc)
219 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
220 ConstructLoc(Loc) {}
221 SharingMapTy() = default;
222 };
223
224 using StackTy = SmallVector<SharingMapTy, 4>;
225
226 /// Stack of used declaration and their data-sharing attributes.
227 DeclSAMapTy Threadprivates;
228 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
229 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
230 /// true, if check for DSA must be from parent directive, false, if
231 /// from current directive.
232 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
233 Sema &SemaRef;
234 bool ForceCapturing = false;
235 /// true if all the variables in the target executable directives must be
236 /// captured by reference.
237 bool ForceCaptureByReferenceInTargetExecutable = false;
238 CriticalsWithHintsTy Criticals;
239 unsigned IgnoredStackElements = 0;
240
241 /// Iterators over the stack iterate in order from innermost to outermost
242 /// directive.
243 using const_iterator = StackTy::const_reverse_iterator;
244 const_iterator begin() const {
245 return Stack.empty() ? const_iterator()
246 : Stack.back().first.rbegin() + IgnoredStackElements;
247 }
248 const_iterator end() const {
249 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
250 }
251 using iterator = StackTy::reverse_iterator;
252 iterator begin() {
253 return Stack.empty() ? iterator()
254 : Stack.back().first.rbegin() + IgnoredStackElements;
255 }
256 iterator end() {
257 return Stack.empty() ? iterator() : Stack.back().first.rend();
258 }
259
260 // Convenience operations to get at the elements of the stack.
261
262 bool isStackEmpty() const {
263 return Stack.empty() ||
264 Stack.back().second != CurrentNonCapturingFunctionScope ||
265 Stack.back().first.size() <= IgnoredStackElements;
266 }
267 size_t getStackSize() const {
268 return isStackEmpty() ? 0
269 : Stack.back().first.size() - IgnoredStackElements;
270 }
271
272 SharingMapTy *getTopOfStackOrNull() {
273 size_t Size = getStackSize();
274 if (Size == 0)
275 return nullptr;
276 return &Stack.back().first[Size - 1];
277 }
278 const SharingMapTy *getTopOfStackOrNull() const {
279 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
280 }
281 SharingMapTy &getTopOfStack() {
282 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", 282, __extension__ __PRETTY_FUNCTION__
))
;
283 return *getTopOfStackOrNull();
284 }
285 const SharingMapTy &getTopOfStack() const {
286 return const_cast<DSAStackTy &>(*this).getTopOfStack();
287 }
288
289 SharingMapTy *getSecondOnStackOrNull() {
290 size_t Size = getStackSize();
291 if (Size <= 1)
292 return nullptr;
293 return &Stack.back().first[Size - 2];
294 }
295 const SharingMapTy *getSecondOnStackOrNull() const {
296 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
297 }
298
299 /// Get the stack element at a certain level (previously returned by
300 /// \c getNestingLevel).
301 ///
302 /// Note that nesting levels count from outermost to innermost, and this is
303 /// the reverse of our iteration order where new inner levels are pushed at
304 /// the front of the stack.
305 SharingMapTy &getStackElemAtLevel(unsigned Level) {
306 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", 306, __extension__ __PRETTY_FUNCTION__
))
;
307 return Stack.back().first[Level];
308 }
309 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
310 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
311 }
312
313 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
314
315 /// Checks if the variable is a local for OpenMP region.
316 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
317
318 /// Vector of previously declared requires directives
319 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
320 /// omp_allocator_handle_t type.
321 QualType OMPAllocatorHandleT;
322 /// omp_depend_t type.
323 QualType OMPDependT;
324 /// omp_event_handle_t type.
325 QualType OMPEventHandleT;
326 /// omp_alloctrait_t type.
327 QualType OMPAlloctraitT;
328 /// Expression for the predefined allocators.
329 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
330 nullptr};
331 /// Vector of previously encountered target directives
332 SmallVector<SourceLocation, 2> TargetLocations;
333 SourceLocation AtomicLocation;
334 /// Vector of declare variant construct traits.
335 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
336
337public:
338 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
339
340 /// Sets omp_allocator_handle_t type.
341 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
342 /// Gets omp_allocator_handle_t type.
343 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
344 /// Sets omp_alloctrait_t type.
345 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
346 /// Gets omp_alloctrait_t type.
347 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
348 /// Sets the given default allocator.
349 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
350 Expr *Allocator) {
351 OMPPredefinedAllocators[AllocatorKind] = Allocator;
352 }
353 /// Returns the specified default allocator.
354 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
355 return OMPPredefinedAllocators[AllocatorKind];
356 }
357 /// Sets omp_depend_t type.
358 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
359 /// Gets omp_depend_t type.
360 QualType getOMPDependT() const { return OMPDependT; }
361
362 /// Sets omp_event_handle_t type.
363 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
364 /// Gets omp_event_handle_t type.
365 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
366
367 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
368 OpenMPClauseKind getClauseParsingMode() const {
369 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", 369, __extension__ __PRETTY_FUNCTION__
))
;
370 return ClauseKindMode;
371 }
372 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
373
374 bool isBodyComplete() const {
375 const SharingMapTy *Top = getTopOfStackOrNull();
376 return Top && Top->BodyComplete;
377 }
378 void setBodyComplete() { getTopOfStack().BodyComplete = true; }
379
380 bool isForceVarCapturing() const { return ForceCapturing; }
381 void setForceVarCapturing(bool V) { ForceCapturing = V; }
382
383 void setForceCaptureByReferenceInTargetExecutable(bool V) {
384 ForceCaptureByReferenceInTargetExecutable = V;
385 }
386 bool isForceCaptureByReferenceInTargetExecutable() const {
387 return ForceCaptureByReferenceInTargetExecutable;
388 }
389
390 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
391 Scope *CurScope, SourceLocation Loc) {
392 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", 393, __extension__ __PRETTY_FUNCTION__
))
393 "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", 393, __extension__ __PRETTY_FUNCTION__
))
;
394 if (Stack.empty() ||
395 Stack.back().second != CurrentNonCapturingFunctionScope)
396 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
397 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
398 Stack.back().first.back().DefaultAttrLoc = Loc;
399 }
400
401 void pop() {
402 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", 403, __extension__ __PRETTY_FUNCTION__
))
403 "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", 403, __extension__ __PRETTY_FUNCTION__
))
;
404 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", 405, __extension__ __PRETTY_FUNCTION__
))
405 "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", 405, __extension__ __PRETTY_FUNCTION__
))
;
406 Stack.back().first.pop_back();
407 }
408
409 /// RAII object to temporarily leave the scope of a directive when we want to
410 /// logically operate in its parent.
411 class ParentDirectiveScope {
412 DSAStackTy &Self;
413 bool Active;
414
415 public:
416 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
417 : Self(Self), Active(false) {
418 if (Activate)
419 enable();
420 }
421 ~ParentDirectiveScope() { disable(); }
422 void disable() {
423 if (Active) {
424 --Self.IgnoredStackElements;
425 Active = false;
426 }
427 }
428 void enable() {
429 if (!Active) {
430 ++Self.IgnoredStackElements;
431 Active = true;
432 }
433 }
434 };
435
436 /// Marks that we're started loop parsing.
437 void loopInit() {
438 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", 439, __extension__ __PRETTY_FUNCTION__
))
439 "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", 439, __extension__ __PRETTY_FUNCTION__
))
;
440 getTopOfStack().LoopStart = true;
441 }
442 /// Start capturing of the variables in the loop context.
443 void loopStart() {
444 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", 445, __extension__ __PRETTY_FUNCTION__
))
445 "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", 445, __extension__ __PRETTY_FUNCTION__
))
;
446 getTopOfStack().LoopStart = false;
447 }
448 /// true, if variables are captured, false otherwise.
449 bool isLoopStarted() const {
450 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", 451, __extension__ __PRETTY_FUNCTION__
))
451 "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", 451, __extension__ __PRETTY_FUNCTION__
))
;
452 return !getTopOfStack().LoopStart;
453 }
454 /// Marks (or clears) declaration as possibly loop counter.
455 void resetPossibleLoopCounter(const Decl *D = nullptr) {
456 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
457 }
458 /// Gets the possible loop counter decl.
459 const Decl *getPossiblyLoopCunter() const {
460 return getTopOfStack().PossiblyLoopCounter;
461 }
462 /// Start new OpenMP region stack in new non-capturing function.
463 void pushFunction() {
464 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", 465, __extension__ __PRETTY_FUNCTION__
))
465 "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", 465, __extension__ __PRETTY_FUNCTION__
))
;
466 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
467 assert(!isa<CapturingScopeInfo>(CurFnScope))(static_cast <bool> (!isa<CapturingScopeInfo>(CurFnScope
)) ? void (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "clang/lib/Sema/SemaOpenMP.cpp", 467, __extension__ __PRETTY_FUNCTION__
))
;
468 CurrentNonCapturingFunctionScope = CurFnScope;
469 }
470 /// Pop region stack for non-capturing function.
471 void popFunction(const FunctionScopeInfo *OldFSI) {
472 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", 473, __extension__ __PRETTY_FUNCTION__
))
473 "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", 473, __extension__ __PRETTY_FUNCTION__
))
;
474 if (!Stack.empty() && Stack.back().second == OldFSI) {
475 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"
, 475, __extension__ __PRETTY_FUNCTION__))
;
476 Stack.pop_back();
477 }
478 CurrentNonCapturingFunctionScope = nullptr;
479 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
480 if (!isa<CapturingScopeInfo>(FSI)) {
481 CurrentNonCapturingFunctionScope = FSI;
482 break;
483 }
484 }
485 }
486
487 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
488 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
489 }
490 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
491 getCriticalWithHint(const DeclarationNameInfo &Name) const {
492 auto I = Criticals.find(Name.getAsString());
493 if (I != Criticals.end())
494 return I->second;
495 return std::make_pair(nullptr, llvm::APSInt());
496 }
497 /// If 'aligned' declaration for given variable \a D was not seen yet,
498 /// add it and return NULL; otherwise return previous occurrence's expression
499 /// for diagnostics.
500 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
501 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
502 /// add it and return NULL; otherwise return previous occurrence's expression
503 /// for diagnostics.
504 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
505
506 /// Register specified variable as loop control variable.
507 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
508 /// Check if the specified variable is a loop control variable for
509 /// current region.
510 /// \return The index of the loop control variable in the list of associated
511 /// for-loops (from outer to inner).
512 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
513 /// Check if the specified variable is a loop control variable for
514 /// parent region.
515 /// \return The index of the loop control variable in the list of associated
516 /// for-loops (from outer to inner).
517 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
518 /// Check if the specified variable is a loop control variable for
519 /// current region.
520 /// \return The index of the loop control variable in the list of associated
521 /// for-loops (from outer to inner).
522 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
523 unsigned Level) const;
524 /// Get the loop control variable for the I-th loop (or nullptr) in
525 /// parent directive.
526 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
527
528 /// Marks the specified decl \p D as used in scan directive.
529 void markDeclAsUsedInScanDirective(ValueDecl *D) {
530 if (SharingMapTy *Stack = getSecondOnStackOrNull())
531 Stack->UsedInScanDirective.insert(D);
532 }
533
534 /// Checks if the specified declaration was used in the inner scan directive.
535 bool isUsedInScanDirective(ValueDecl *D) const {
536 if (const SharingMapTy *Stack = getTopOfStackOrNull())
537 return Stack->UsedInScanDirective.contains(D);
538 return false;
539 }
540
541 /// Adds explicit data sharing attribute to the specified declaration.
542 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
543 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
544 bool AppliedToPointee = false);
545
546 /// Adds additional information for the reduction items with the reduction id
547 /// represented as an operator.
548 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
549 BinaryOperatorKind BOK);
550 /// Adds additional information for the reduction items with the reduction id
551 /// represented as reduction identifier.
552 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
553 const Expr *ReductionRef);
554 /// Returns the location and reduction operation from the innermost parent
555 /// region for the given \p D.
556 const DSAVarData
557 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
558 BinaryOperatorKind &BOK,
559 Expr *&TaskgroupDescriptor) const;
560 /// Returns the location and reduction operation from the innermost parent
561 /// region for the given \p D.
562 const DSAVarData
563 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
564 const Expr *&ReductionRef,
565 Expr *&TaskgroupDescriptor) const;
566 /// Return reduction reference expression for the current taskgroup or
567 /// parallel/worksharing directives with task reductions.
568 Expr *getTaskgroupReductionRef() const {
569 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", 574, __extension__ __PRETTY_FUNCTION__
))
570 ((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", 574, __extension__ __PRETTY_FUNCTION__
))
571 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", 574, __extension__ __PRETTY_FUNCTION__
))
572 !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", 574, __extension__ __PRETTY_FUNCTION__
))
573 "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", 574, __extension__ __PRETTY_FUNCTION__
))
574 "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", 574, __extension__ __PRETTY_FUNCTION__
))
;
575 return getTopOfStack().TaskgroupReductionRef;
576 }
577 /// Checks if the given \p VD declaration is actually a taskgroup reduction
578 /// descriptor variable at the \p Level of OpenMP regions.
579 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
580 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
581 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
582 ->getDecl() == VD;
583 }
584
585 /// Returns data sharing attributes from top of the stack for the
586 /// specified declaration.
587 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
588 /// Returns data-sharing attributes for the specified declaration.
589 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
590 /// Returns data-sharing attributes for the specified declaration.
591 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
592 /// Checks if the specified variables has data-sharing attributes which
593 /// match specified \a CPred predicate in any directive which matches \a DPred
594 /// predicate.
595 const DSAVarData
596 hasDSA(ValueDecl *D,
597 const llvm::function_ref<bool(OpenMPClauseKind, bool,
598 DefaultDataSharingAttributes)>
599 CPred,
600 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
601 bool FromParent) const;
602 /// Checks if the specified variables has data-sharing attributes which
603 /// match specified \a CPred predicate in any innermost directive which
604 /// matches \a DPred predicate.
605 const DSAVarData
606 hasInnermostDSA(ValueDecl *D,
607 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
608 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
609 bool FromParent) const;
610 /// Checks if the specified variables has explicit data-sharing
611 /// attributes which match specified \a CPred predicate at the specified
612 /// OpenMP region.
613 bool
614 hasExplicitDSA(const ValueDecl *D,
615 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
616 unsigned Level, bool NotLastprivate = false) const;
617
618 /// Returns true if the directive at level \Level matches in the
619 /// specified \a DPred predicate.
620 bool hasExplicitDirective(
621 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
622 unsigned Level) const;
623
624 /// Finds a directive which matches specified \a DPred predicate.
625 bool hasDirective(
626 const llvm::function_ref<bool(
627 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
628 DPred,
629 bool FromParent) const;
630
631 /// Returns currently analyzed directive.
632 OpenMPDirectiveKind getCurrentDirective() const {
633 const SharingMapTy *Top = getTopOfStackOrNull();
634 return Top ? Top->Directive : OMPD_unknown;
635 }
636 /// Returns directive kind at specified level.
637 OpenMPDirectiveKind getDirective(unsigned Level) const {
638 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", 638, __extension__ __PRETTY_FUNCTION__
))
;
639 return getStackElemAtLevel(Level).Directive;
640 }
641 /// Returns the capture region at the specified level.
642 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
643 unsigned OpenMPCaptureLevel) const {
644 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
645 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
646 return CaptureRegions[OpenMPCaptureLevel];
647 }
648 /// Returns parent directive.
649 OpenMPDirectiveKind getParentDirective() const {
650 const SharingMapTy *Parent = getSecondOnStackOrNull();
651 return Parent ? Parent->Directive : OMPD_unknown;
652 }
653
654 /// Add requires decl to internal vector
655 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
656
657 /// Checks if the defined 'requires' directive has specified type of clause.
658 template <typename ClauseType> bool hasRequiresDeclWithClause() const {
659 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
660 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
661 return isa<ClauseType>(C);
662 });
663 });
664 }
665
666 /// Checks for a duplicate clause amongst previously declared requires
667 /// directives
668 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
669 bool IsDuplicate = false;
670 for (OMPClause *CNew : ClauseList) {
671 for (const OMPRequiresDecl *D : RequiresDecls) {
672 for (const OMPClause *CPrev : D->clauselists()) {
673 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
674 SemaRef.Diag(CNew->getBeginLoc(),
675 diag::err_omp_requires_clause_redeclaration)
676 << getOpenMPClauseName(CNew->getClauseKind());
677 SemaRef.Diag(CPrev->getBeginLoc(),
678 diag::note_omp_requires_previous_clause)
679 << getOpenMPClauseName(CPrev->getClauseKind());
680 IsDuplicate = true;
681 }
682 }
683 }
684 }
685 return IsDuplicate;
686 }
687
688 /// Add location of previously encountered target to internal vector
689 void addTargetDirLocation(SourceLocation LocStart) {
690 TargetLocations.push_back(LocStart);
691 }
692
693 /// Add location for the first encountered atomicc directive.
694 void addAtomicDirectiveLoc(SourceLocation Loc) {
695 if (AtomicLocation.isInvalid())
696 AtomicLocation = Loc;
697 }
698
699 /// Returns the location of the first encountered atomic directive in the
700 /// module.
701 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
702
703 // Return previously encountered target region locations.
704 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
705 return TargetLocations;
706 }
707
708 /// Set default data sharing attribute to none.
709 void setDefaultDSANone(SourceLocation Loc) {
710 getTopOfStack().DefaultAttr = DSA_none;
711 getTopOfStack().DefaultAttrLoc = Loc;
712 }
713 /// Set default data sharing attribute to shared.
714 void setDefaultDSAShared(SourceLocation Loc) {
715 getTopOfStack().DefaultAttr = DSA_shared;
716 getTopOfStack().DefaultAttrLoc = Loc;
717 }
718 /// Set default data sharing attribute to private.
719 void setDefaultDSAPrivate(SourceLocation Loc) {
720 getTopOfStack().DefaultAttr = DSA_private;
721 getTopOfStack().DefaultAttrLoc = Loc;
722 }
723 /// Set default data sharing attribute to firstprivate.
724 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
725 getTopOfStack().DefaultAttr = DSA_firstprivate;
726 getTopOfStack().DefaultAttrLoc = Loc;
727 }
728 /// Set default data mapping attribute to Modifier:Kind
729 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
730 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
731 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
732 DMI.ImplicitBehavior = M;
733 DMI.SLoc = Loc;
734 }
735 /// Check whether the implicit-behavior has been set in defaultmap
736 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
737 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
738 return getTopOfStack()
739 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
740 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
741 getTopOfStack()
742 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
743 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
744 getTopOfStack()
745 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
746 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
747 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
748 OMPC_DEFAULTMAP_MODIFIER_unknown;
749 }
750
751 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
752 return ConstructTraits;
753 }
754 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
755 bool ScopeEntry) {
756 if (ScopeEntry)
757 ConstructTraits.append(Traits.begin(), Traits.end());
758 else
759 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
760 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
761 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", 761, __extension__ __PRETTY_FUNCTION__
))
;
762 (void)Trait;
763 (void)Top;
764 }
765 }
766
767 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
768 return getStackSize() <= Level ? DSA_unspecified
769 : getStackElemAtLevel(Level).DefaultAttr;
770 }
771 DefaultDataSharingAttributes getDefaultDSA() const {
772 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
773 }
774 SourceLocation getDefaultDSALocation() const {
775 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
776 }
777 OpenMPDefaultmapClauseModifier
778 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
779 return isStackEmpty()
780 ? OMPC_DEFAULTMAP_MODIFIER_unknown
781 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
782 }
783 OpenMPDefaultmapClauseModifier
784 getDefaultmapModifierAtLevel(unsigned Level,
785 OpenMPDefaultmapClauseKind Kind) const {
786 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
787 }
788 bool isDefaultmapCapturedByRef(unsigned Level,
789 OpenMPDefaultmapClauseKind Kind) const {
790 OpenMPDefaultmapClauseModifier M =
791 getDefaultmapModifierAtLevel(Level, Kind);
792 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
793 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
794 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
795 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
796 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
797 }
798 return true;
799 }
800 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
801 OpenMPDefaultmapClauseKind Kind) {
802 switch (Kind) {
803 case OMPC_DEFAULTMAP_scalar:
804 case OMPC_DEFAULTMAP_pointer:
805 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
806 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
807 (M == OMPC_DEFAULTMAP_MODIFIER_default);
808 case OMPC_DEFAULTMAP_aggregate:
809 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
810 default:
811 break;
812 }
813 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "clang/lib/Sema/SemaOpenMP.cpp", 813)
;
814 }
815 bool mustBeFirstprivateAtLevel(unsigned Level,
816 OpenMPDefaultmapClauseKind Kind) const {
817 OpenMPDefaultmapClauseModifier M =
818 getDefaultmapModifierAtLevel(Level, Kind);
819 return mustBeFirstprivateBase(M, Kind);
820 }
821 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
822 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
823 return mustBeFirstprivateBase(M, Kind);
824 }
825
826 /// Checks if the specified variable is a threadprivate.
827 bool isThreadPrivate(VarDecl *D) {
828 const DSAVarData DVar = getTopDSA(D, false);
829 return isOpenMPThreadPrivate(DVar.CKind);
830 }
831
832 /// Marks current region as ordered (it has an 'ordered' clause).
833 void setOrderedRegion(bool IsOrdered, const Expr *Param,
834 OMPOrderedClause *Clause) {
835 if (IsOrdered)
836 getTopOfStack().OrderedRegion.emplace(Param, Clause);
837 else
838 getTopOfStack().OrderedRegion.reset();
839 }
840 /// Returns true, if region is ordered (has associated 'ordered' clause),
841 /// false - otherwise.
842 bool isOrderedRegion() const {
843 if (const SharingMapTy *Top = getTopOfStackOrNull())
844 return Top->OrderedRegion.has_value();
845 return false;
846 }
847 /// Returns optional parameter for the ordered region.
848 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
849 if (const SharingMapTy *Top = getTopOfStackOrNull())
850 if (Top->OrderedRegion)
851 return *Top->OrderedRegion;
852 return std::make_pair(nullptr, nullptr);
853 }
854 /// Returns true, if parent region is ordered (has associated
855 /// 'ordered' clause), false - otherwise.
856 bool isParentOrderedRegion() const {
857 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
858 return Parent->OrderedRegion.has_value();
859 return false;
860 }
861 /// Returns optional parameter for the ordered region.
862 std::pair<const Expr *, OMPOrderedClause *>
863 getParentOrderedRegionParam() const {
864 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
865 if (Parent->OrderedRegion)
866 return *Parent->OrderedRegion;
867 return std::make_pair(nullptr, nullptr);
868 }
869 /// Marks current region as having an 'order' clause.
870 void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
871 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
872 }
873 /// Returns true, if parent region is order (has associated
874 /// 'order' clause), false - otherwise.
875 bool isParentOrderConcurrent() const {
876 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
877 return Parent->RegionHasOrderConcurrent;
878 return false;
879 }
880 /// Marks current region as nowait (it has a 'nowait' clause).
881 void setNowaitRegion(bool IsNowait = true) {
882 getTopOfStack().NowaitRegion = IsNowait;
883 }
884 /// Returns true, if parent region is nowait (has associated
885 /// 'nowait' clause), false - otherwise.
886 bool isParentNowaitRegion() const {
887 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
888 return Parent->NowaitRegion;
889 return false;
890 }
891 /// Marks current region as untied (it has a 'untied' clause).
892 void setUntiedRegion(bool IsUntied = true) {
893 getTopOfStack().UntiedRegion = IsUntied;
894 }
895 /// Return true if current region is untied.
896 bool isUntiedRegion() const {
897 const SharingMapTy *Top = getTopOfStackOrNull();
898 return Top ? Top->UntiedRegion : false;
899 }
900 /// Marks parent region as cancel region.
901 void setParentCancelRegion(bool Cancel = true) {
902 if (SharingMapTy *Parent = getSecondOnStackOrNull())
903 Parent->CancelRegion |= Cancel;
904 }
905 /// Return true if current region has inner cancel construct.
906 bool isCancelRegion() const {
907 const SharingMapTy *Top = getTopOfStackOrNull();
908 return Top ? Top->CancelRegion : false;
909 }
910
911 /// Mark that parent region already has scan directive.
912 void setParentHasScanDirective(SourceLocation Loc) {
913 if (SharingMapTy *Parent = getSecondOnStackOrNull())
914 Parent->PrevScanLocation = Loc;
915 }
916 /// Return true if current region has inner cancel construct.
917 bool doesParentHasScanDirective() const {
918 const SharingMapTy *Top = getSecondOnStackOrNull();
919 return Top ? Top->PrevScanLocation.isValid() : false;
920 }
921 /// Return true if current region has inner cancel construct.
922 SourceLocation getParentScanDirectiveLoc() const {
923 const SharingMapTy *Top = getSecondOnStackOrNull();
924 return Top ? Top->PrevScanLocation : SourceLocation();
925 }
926 /// Mark that parent region already has ordered directive.
927 void setParentHasOrderedDirective(SourceLocation Loc) {
928 if (SharingMapTy *Parent = getSecondOnStackOrNull())
929 Parent->PrevOrderedLocation = Loc;
930 }
931 /// Return true if current region has inner ordered construct.
932 bool doesParentHasOrderedDirective() const {
933 const SharingMapTy *Top = getSecondOnStackOrNull();
934 return Top ? Top->PrevOrderedLocation.isValid() : false;
935 }
936 /// Returns the location of the previously specified ordered directive.
937 SourceLocation getParentOrderedDirectiveLoc() const {
938 const SharingMapTy *Top = getSecondOnStackOrNull();
939 return Top ? Top->PrevOrderedLocation : SourceLocation();
940 }
941
942 /// Set collapse value for the region.
943 void setAssociatedLoops(unsigned Val) {
944 getTopOfStack().AssociatedLoops = Val;
945 if (Val > 1)
946 getTopOfStack().HasMutipleLoops = true;
947 }
948 /// Return collapse value for region.
949 unsigned getAssociatedLoops() const {
950 const SharingMapTy *Top = getTopOfStackOrNull();
951 return Top ? Top->AssociatedLoops : 0;
952 }
953 /// Returns true if the construct is associated with multiple loops.
954 bool hasMutipleLoops() const {
955 const SharingMapTy *Top = getTopOfStackOrNull();
956 return Top ? Top->HasMutipleLoops : false;
957 }
958
959 /// Marks current target region as one with closely nested teams
960 /// region.
961 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
962 if (SharingMapTy *Parent = getSecondOnStackOrNull())
963 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
964 }
965 /// Returns true, if current region has closely nested teams region.
966 bool hasInnerTeamsRegion() const {
967 return getInnerTeamsRegionLoc().isValid();
968 }
969 /// Returns location of the nested teams region (if any).
970 SourceLocation getInnerTeamsRegionLoc() const {
971 const SharingMapTy *Top = getTopOfStackOrNull();
972 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
973 }
974
975 Scope *getCurScope() const {
976 const SharingMapTy *Top = getTopOfStackOrNull();
977 return Top ? Top->CurScope : nullptr;
978 }
979 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
980 SourceLocation getConstructLoc() const {
981 const SharingMapTy *Top = getTopOfStackOrNull();
982 return Top ? Top->ConstructLoc : SourceLocation();
983 }
984
985 /// Do the check specified in \a Check to all component lists and return true
986 /// if any issue is found.
987 bool checkMappableExprComponentListsForDecl(
988 const ValueDecl *VD, bool CurrentRegionOnly,
989 const llvm::function_ref<
990 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
991 OpenMPClauseKind)>
992 Check) const {
993 if (isStackEmpty())
994 return false;
995 auto SI = begin();
996 auto SE = end();
997
998 if (SI == SE)
999 return false;
1000
1001 if (CurrentRegionOnly)
1002 SE = std::next(SI);
1003 else
1004 std::advance(SI, 1);
1005
1006 for (; SI != SE; ++SI) {
1007 auto MI = SI->MappedExprComponents.find(VD);
1008 if (MI != SI->MappedExprComponents.end())
1009 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1010 MI->second.Components)
1011 if (Check(L, MI->second.Kind))
1012 return true;
1013 }
1014 return false;
1015 }
1016
1017 /// Do the check specified in \a Check to all component lists at a given level
1018 /// and return true if any issue is found.
1019 bool checkMappableExprComponentListsForDeclAtLevel(
1020 const ValueDecl *VD, unsigned Level,
1021 const llvm::function_ref<
1022 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1023 OpenMPClauseKind)>
1024 Check) const {
1025 if (getStackSize() <= Level)
1026 return false;
1027
1028 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1029 auto MI = StackElem.MappedExprComponents.find(VD);
1030 if (MI != StackElem.MappedExprComponents.end())
1031 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1032 MI->second.Components)
1033 if (Check(L, MI->second.Kind))
1034 return true;
1035 return false;
1036 }
1037
1038 /// Create a new mappable expression component list associated with a given
1039 /// declaration and initialize it with the provided list of components.
1040 void addMappableExpressionComponents(
1041 const ValueDecl *VD,
1042 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1043 OpenMPClauseKind WhereFoundClauseKind) {
1044 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1045 // Create new entry and append the new components there.
1046 MEC.Components.resize(MEC.Components.size() + 1);
1047 MEC.Components.back().append(Components.begin(), Components.end());
1048 MEC.Kind = WhereFoundClauseKind;
1049 }
1050
1051 unsigned getNestingLevel() const {
1052 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "clang/lib/Sema/SemaOpenMP.cpp", 1052, __extension__
__PRETTY_FUNCTION__))
;
1053 return getStackSize() - 1;
1054 }
1055 void addDoacrossDependClause(OMPDependClause *C,
1056 const OperatorOffsetTy &OpsOffs) {
1057 SharingMapTy *Parent = getSecondOnStackOrNull();
1058 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", 1058, __extension__ __PRETTY_FUNCTION__
))
;
1059 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1060 }
1061 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1062 getDoacrossDependClauses() const {
1063 const SharingMapTy &StackElem = getTopOfStack();
1064 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1065 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1066 return llvm::make_range(Ref.begin(), Ref.end());
1067 }
1068 return llvm::make_range(StackElem.DoacrossDepends.end(),
1069 StackElem.DoacrossDepends.end());
1070 }
1071
1072 // Store types of classes which have been explicitly mapped
1073 void addMappedClassesQualTypes(QualType QT) {
1074 SharingMapTy &StackElem = getTopOfStack();
1075 StackElem.MappedClassesQualTypes.insert(QT);
1076 }
1077
1078 // Return set of mapped classes types
1079 bool isClassPreviouslyMapped(QualType QT) const {
1080 const SharingMapTy &StackElem = getTopOfStack();
1081 return StackElem.MappedClassesQualTypes.contains(QT);
1082 }
1083
1084 /// Adds global declare target to the parent target region.
1085 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1086 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", 1088, __extension__ __PRETTY_FUNCTION__
))
1087 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", 1088, __extension__ __PRETTY_FUNCTION__
))
1088 "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", 1088, __extension__ __PRETTY_FUNCTION__
))
;
1089 for (auto &Elem : *this) {
1090 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1091 Elem.DeclareTargetLinkVarDecls.push_back(E);
1092 return;
1093 }
1094 }
1095 }
1096
1097 /// Returns the list of globals with declare target link if current directive
1098 /// is target.
1099 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1100 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", 1101, __extension__ __PRETTY_FUNCTION__
))
1101 "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", 1101, __extension__ __PRETTY_FUNCTION__
))
;
1102 return getTopOfStack().DeclareTargetLinkVarDecls;
1103 }
1104
1105 /// Adds list of allocators expressions.
1106 void addInnerAllocatorExpr(Expr *E) {
1107 getTopOfStack().InnerUsedAllocators.push_back(E);
1108 }
1109 /// Return list of used allocators.
1110 ArrayRef<Expr *> getInnerAllocators() const {
1111 return getTopOfStack().InnerUsedAllocators;
1112 }
1113 /// Marks the declaration as implicitly firstprivate nin the task-based
1114 /// regions.
1115 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1116 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1117 }
1118 /// Checks if the decl is implicitly firstprivate in the task-based region.
1119 bool isImplicitTaskFirstprivate(Decl *D) const {
1120 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1121 }
1122
1123 /// Marks decl as used in uses_allocators clause as the allocator.
1124 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1125 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1126 }
1127 /// Checks if specified decl is used in uses allocator clause as the
1128 /// allocator.
1129 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1130 const Decl *D) const {
1131 const SharingMapTy &StackElem = getTopOfStack();
1132 auto I = StackElem.UsesAllocatorsDecls.find(D);
1133 if (I == StackElem.UsesAllocatorsDecls.end())
1134 return std::nullopt;
1135 return I->getSecond();
1136 }
1137 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1138 const SharingMapTy &StackElem = getTopOfStack();
1139 auto I = StackElem.UsesAllocatorsDecls.find(D);
1140 if (I == StackElem.UsesAllocatorsDecls.end())
1141 return std::nullopt;
1142 return I->getSecond();
1143 }
1144
1145 void addDeclareMapperVarRef(Expr *Ref) {
1146 SharingMapTy &StackElem = getTopOfStack();
1147 StackElem.DeclareMapperVar = Ref;
1148 }
1149 const Expr *getDeclareMapperVarRef() const {
1150 const SharingMapTy *Top = getTopOfStackOrNull();
1151 return Top ? Top->DeclareMapperVar : nullptr;
1152 }
1153 /// get captured field from ImplicitDefaultFirstprivateFDs
1154 VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1155 const_iterator I = begin();
1156 const_iterator EndI = end();
1157 size_t StackLevel = getStackSize();
1158 for (; I != EndI; ++I) {
1159 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1160 break;
1161 StackLevel--;
1162 }
1163 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI))(static_cast <bool> ((StackLevel > 0 && I !=
EndI) || (StackLevel == 0 && I == EndI)) ? void (0) :
__assert_fail ("(StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1163, __extension__ __PRETTY_FUNCTION__
))
;
1164 if (I == EndI)
1165 return nullptr;
1166 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1167 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1168 return IFD.VD;
1169 return nullptr;
1170 }
1171 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1172 bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1173 const_iterator I = begin();
1174 const_iterator EndI = end();
1175 for (; I != EndI; ++I)
1176 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1177 break;
1178 if (I == EndI)
1179 return false;
1180 for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1181 if (IFD.VD == VD)
1182 return true;
1183 return false;
1184 }
1185 /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1186 void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1187 iterator I = begin();
1188 const_iterator EndI = end();
1189 size_t StackLevel = getStackSize();
1190 for (; I != EndI; ++I) {
1191 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1192 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1193 break;
1194 }
1195 StackLevel--;
1196 }
1197 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI))(static_cast <bool> ((StackLevel > 0 && I !=
EndI) || (StackLevel == 0 && I == EndI)) ? void (0) :
__assert_fail ("(StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI)"
, "clang/lib/Sema/SemaOpenMP.cpp", 1197, __extension__ __PRETTY_FUNCTION__
))
;
1198 }
1199};
1200
1201bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1202 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1203}
1204
1205bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1206 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1207 DKind == OMPD_unknown;
1208}
1209
1210} // namespace
1211
1212static const Expr *getExprAsWritten(const Expr *E) {
1213 if (const auto *FE = dyn_cast<FullExpr>(E))
1214 E = FE->getSubExpr();
1215
1216 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1217 E = MTE->getSubExpr();
1218
1219 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1220 E = Binder->getSubExpr();
1221
1222 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1223 E = ICE->getSubExprAsWritten();
1224 return E->IgnoreParens();
1225}
1226
1227static Expr *getExprAsWritten(Expr *E) {
1228 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1229}
1230
1231static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1232 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1233 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1234 D = ME->getMemberDecl();
1235 const auto *VD = dyn_cast<VarDecl>(D);
1236 const auto *FD = dyn_cast<FieldDecl>(D);
1237 if (VD != nullptr) {
1238 VD = VD->getCanonicalDecl();
1239 D = VD;
1240 } else {
1241 assert(FD)(static_cast <bool> (FD) ? void (0) : __assert_fail ("FD"
, "clang/lib/Sema/SemaOpenMP.cpp", 1241, __extension__ __PRETTY_FUNCTION__
))
;
1242 FD = FD->getCanonicalDecl();
1243 D = FD;
1244 }
1245 return D;
1246}
1247
1248static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1249 return const_cast<ValueDecl *>(
1250 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1251}
1252
1253DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1254 ValueDecl *D) const {
1255 D = getCanonicalDecl(D);
1256 auto *VD = dyn_cast<VarDecl>(D);
1257 const auto *FD = dyn_cast<FieldDecl>(D);
1258 DSAVarData DVar;
1259 if (Iter == end()) {
1260 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1261 // in a region but not in construct]
1262 // File-scope or namespace-scope variables referenced in called routines
1263 // in the region are shared unless they appear in a threadprivate
1264 // directive.
1265 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1266 DVar.CKind = OMPC_shared;
1267
1268 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1269 // in a region but not in construct]
1270 // Variables with static storage duration that are declared in called
1271 // routines in the region are shared.
1272 if (VD && VD->hasGlobalStorage())
1273 DVar.CKind = OMPC_shared;
1274
1275 // Non-static data members are shared by default.
1276 if (FD)
1277 DVar.CKind = OMPC_shared;
1278
1279 return DVar;
1280 }
1281
1282 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1283 // in a Construct, C/C++, predetermined, p.1]
1284 // Variables with automatic storage duration that are declared in a scope
1285 // inside the construct are private.
1286 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1287 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1288 DVar.CKind = OMPC_private;
1289 return DVar;
1290 }
1291
1292 DVar.DKind = Iter->Directive;
1293 // Explicitly specified attributes and local variables with predetermined
1294 // attributes.
1295 if (Iter->SharingMap.count(D)) {
1296 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1297 DVar.RefExpr = Data.RefExpr.getPointer();
1298 DVar.PrivateCopy = Data.PrivateCopy;
1299 DVar.CKind = Data.Attributes;
1300 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1301 DVar.Modifier = Data.Modifier;
1302 DVar.AppliedToPointee = Data.AppliedToPointee;
1303 return DVar;
1304 }
1305
1306 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1307 // in a Construct, C/C++, implicitly determined, p.1]
1308 // In a parallel or task construct, the data-sharing attributes of these
1309 // variables are determined by the default clause, if present.
1310 switch (Iter->DefaultAttr) {
1311 case DSA_shared:
1312 DVar.CKind = OMPC_shared;
1313 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1314 return DVar;
1315 case DSA_none:
1316 return DVar;
1317 case DSA_firstprivate:
1318 if (VD && VD->getStorageDuration() == SD_Static &&
1319 VD->getDeclContext()->isFileContext()) {
1320 DVar.CKind = OMPC_unknown;
1321 } else {
1322 DVar.CKind = OMPC_firstprivate;
1323 }
1324 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1325 return DVar;
1326 case DSA_private:
1327 // each variable with static storage duration that is declared
1328 // in a namespace or global scope and referenced in the construct,
1329 // and that does not have a predetermined data-sharing attribute
1330 if (VD && VD->getStorageDuration() == SD_Static &&
1331 VD->getDeclContext()->isFileContext()) {
1332 DVar.CKind = OMPC_unknown;
1333 } else {
1334 DVar.CKind = OMPC_private;
1335 }
1336 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1337 return DVar;
1338 case DSA_unspecified:
1339 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1340 // in a Construct, implicitly determined, p.2]
1341 // In a parallel construct, if no default clause is present, these
1342 // variables are shared.
1343 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1344 if ((isOpenMPParallelDirective(DVar.DKind) &&
1345 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1346 isOpenMPTeamsDirective(DVar.DKind)) {
1347 DVar.CKind = OMPC_shared;
1348 return DVar;
1349 }
1350
1351 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1352 // in a Construct, implicitly determined, p.4]
1353 // In a task construct, if no default clause is present, a variable that in
1354 // the enclosing context is determined to be shared by all implicit tasks
1355 // bound to the current team is shared.
1356 if (isOpenMPTaskingDirective(DVar.DKind)) {
1357 DSAVarData DVarTemp;
1358 const_iterator I = Iter, E = end();
1359 do {
1360 ++I;
1361 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1362 // Referenced in a Construct, implicitly determined, p.6]
1363 // In a task construct, if no default clause is present, a variable
1364 // whose data-sharing attribute is not determined by the rules above is
1365 // firstprivate.
1366 DVarTemp = getDSA(I, D);
1367 if (DVarTemp.CKind != OMPC_shared) {
1368 DVar.RefExpr = nullptr;
1369 DVar.CKind = OMPC_firstprivate;
1370 return DVar;
1371 }
1372 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1373 DVar.CKind =
1374 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1375 return DVar;
1376 }
1377 }
1378 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1379 // in a Construct, implicitly determined, p.3]
1380 // For constructs other than task, if no default clause is present, these
1381 // variables inherit their data-sharing attributes from the enclosing
1382 // context.
1383 return getDSA(++Iter, D);
1384}
1385
1386const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1387 const Expr *NewDE) {
1388 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", 1388, __extension__ __PRETTY_FUNCTION__
))
;
1389 D = getCanonicalDecl(D);
1390 SharingMapTy &StackElem = getTopOfStack();
1391 auto It = StackElem.AlignedMap.find(D);
1392 if (It == StackElem.AlignedMap.end()) {
1393 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", 1393, __extension__ __PRETTY_FUNCTION__
))
;
1394 StackElem.AlignedMap[D] = NewDE;
1395 return nullptr;
1396 }
1397 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", 1397, __extension__ __PRETTY_FUNCTION__
))
;
1398 return It->second;
1399}
1400
1401const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1402 const Expr *NewDE) {
1403 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", 1403, __extension__ __PRETTY_FUNCTION__
))
;
1404 D = getCanonicalDecl(D);
1405 SharingMapTy &StackElem = getTopOfStack();
1406 auto It = StackElem.NontemporalMap.find(D);
1407 if (It == StackElem.NontemporalMap.end()) {
1408 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", 1408, __extension__ __PRETTY_FUNCTION__
))
;
1409 StackElem.NontemporalMap[D] = NewDE;
1410 return nullptr;
1411 }
1412 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", 1412, __extension__ __PRETTY_FUNCTION__
))
;
1413 return It->second;
1414}
1415
1416void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1417 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", 1417, __extension__ __PRETTY_FUNCTION__
))
;
1418 D = getCanonicalDecl(D);
1419 SharingMapTy &StackElem = getTopOfStack();
1420 StackElem.LCVMap.try_emplace(
1421 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1422}
1423
1424const DSAStackTy::LCDeclInfo
1425DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1426 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", 1426, __extension__ __PRETTY_FUNCTION__
))
;
1427 D = getCanonicalDecl(D);
1428 const SharingMapTy &StackElem = getTopOfStack();
1429 auto It = StackElem.LCVMap.find(D);
1430 if (It != StackElem.LCVMap.end())
1431 return It->second;
1432 return {0, nullptr};
1433}
1434
1435const DSAStackTy::LCDeclInfo
1436DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1437 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", 1437, __extension__ __PRETTY_FUNCTION__
))
;
1438 D = getCanonicalDecl(D);
1439 for (unsigned I = Level + 1; I > 0; --I) {
1440 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1441 auto It = StackElem.LCVMap.find(D);
1442 if (It != StackElem.LCVMap.end())
1443 return It->second;
1444 }
1445 return {0, nullptr};
1446}
1447
1448const DSAStackTy::LCDeclInfo
1449DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1450 const SharingMapTy *Parent = getSecondOnStackOrNull();
1451 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", 1451, __extension__ __PRETTY_FUNCTION__
))
;
1452 D = getCanonicalDecl(D);
1453 auto It = Parent->LCVMap.find(D);
1454 if (It != Parent->LCVMap.end())
1455 return It->second;
1456 return {0, nullptr};
1457}
1458
1459const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1460 const SharingMapTy *Parent = getSecondOnStackOrNull();
1461 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", 1461, __extension__ __PRETTY_FUNCTION__
))
;
1462 if (Parent->LCVMap.size() < I)
1463 return nullptr;
1464 for (const auto &Pair : Parent->LCVMap)
1465 if (Pair.second.first == I)
1466 return Pair.first;
1467 return nullptr;
1468}
1469
1470void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1471 DeclRefExpr *PrivateCopy, unsigned Modifier,
1472 bool AppliedToPointee) {
1473 D = getCanonicalDecl(D);
1474 if (A == OMPC_threadprivate) {
1475 DSAInfo &Data = Threadprivates[D];
1476 Data.Attributes = A;
1477 Data.RefExpr.setPointer(E);
1478 Data.PrivateCopy = nullptr;
1479 Data.Modifier = Modifier;
1480 } else {
1481 DSAInfo &Data = getTopOfStack().SharingMap[D];
1482 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", 1485, __extension__ __PRETTY_FUNCTION__
))
1483 (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", 1485, __extension__ __PRETTY_FUNCTION__
))
1484 (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", 1485, __extension__ __PRETTY_FUNCTION__
))
1485 (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", 1485, __extension__ __PRETTY_FUNCTION__
))
;
1486 Data.Modifier = Modifier;
1487 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1488 Data.RefExpr.setInt(/*IntVal=*/true);
1489 return;
1490 }
1491 const bool IsLastprivate =
1492 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1493 Data.Attributes = A;
1494 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1495 Data.PrivateCopy = PrivateCopy;
1496 Data.AppliedToPointee = AppliedToPointee;
1497 if (PrivateCopy) {
1498 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1499 Data.Modifier = Modifier;
1500 Data.Attributes = A;
1501 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1502 Data.PrivateCopy = nullptr;
1503 Data.AppliedToPointee = AppliedToPointee;
1504 }
1505 }
1506}
1507
1508/// Build a variable declaration for OpenMP loop iteration variable.
1509static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1510 StringRef Name, const AttrVec *Attrs = nullptr,
1511 DeclRefExpr *OrigRef = nullptr) {
1512 DeclContext *DC = SemaRef.CurContext;
1513 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1514 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1515 auto *Decl =
1516 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1517 if (Attrs) {
1518 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1519 I != E; ++I)
1520 Decl->addAttr(*I);
1521 }
1522 Decl->setImplicit();
1523 if (OrigRef) {
1524 Decl->addAttr(
1525 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1526 }
1527 return Decl;
1528}
1529
1530static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1531 SourceLocation Loc,
1532 bool RefersToCapture = false) {
1533 D->setReferenced();
1534 D->markUsed(S.Context);
1535 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1536 SourceLocation(), D, RefersToCapture, Loc, Ty,
1537 VK_LValue);
1538}
1539
1540void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1541 BinaryOperatorKind BOK) {
1542 D = getCanonicalDecl(D);
1543 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", 1543, __extension__ __PRETTY_FUNCTION__
))
;
1544 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", 1546, __extension__ __PRETTY_FUNCTION__
))
1545 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", 1546, __extension__ __PRETTY_FUNCTION__
))
1546 "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", 1546, __extension__ __PRETTY_FUNCTION__
))
;
1547 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1548 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", 1554, __extension__ __PRETTY_FUNCTION__
))
1549 (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", 1554, __extension__ __PRETTY_FUNCTION__
))
1550 ((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", 1554, __extension__ __PRETTY_FUNCTION__
))
1551 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", 1554, __extension__ __PRETTY_FUNCTION__
))
1552 !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", 1554, __extension__ __PRETTY_FUNCTION__
))
1553 "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", 1554, __extension__ __PRETTY_FUNCTION__
))
1554 "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", 1554, __extension__ __PRETTY_FUNCTION__
))
;
1555 ReductionData.set(BOK, SR);
1556 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1557 if (!TaskgroupReductionRef) {
1558 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1559 SemaRef.Context.VoidPtrTy, ".task_red.");
1560 TaskgroupReductionRef =
1561 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1562 }
1563}
1564
1565void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1566 const Expr *ReductionRef) {
1567 D = getCanonicalDecl(D);
1568 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", 1568, __extension__ __PRETTY_FUNCTION__
))
;
1569 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", 1571, __extension__ __PRETTY_FUNCTION__
))
1570 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", 1571, __extension__ __PRETTY_FUNCTION__
))
1571 "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", 1571, __extension__ __PRETTY_FUNCTION__
))
;
1572 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1573 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", 1579, __extension__ __PRETTY_FUNCTION__
))
1574 (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", 1579, __extension__ __PRETTY_FUNCTION__
))
1575 ((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", 1579, __extension__ __PRETTY_FUNCTION__
))
1576 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", 1579, __extension__ __PRETTY_FUNCTION__
))
1577 !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", 1579, __extension__ __PRETTY_FUNCTION__
))
1578 "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", 1579, __extension__ __PRETTY_FUNCTION__
))
1579 "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", 1579, __extension__ __PRETTY_FUNCTION__
))
;
1580 ReductionData.set(ReductionRef, SR);
1581 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1582 if (!TaskgroupReductionRef) {
1583 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1584 SemaRef.Context.VoidPtrTy, ".task_red.");
1585 TaskgroupReductionRef =
1586 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1587 }
1588}
1589
1590const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1591 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1592 Expr *&TaskgroupDescriptor) const {
1593 D = getCanonicalDecl(D);
1594 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", 1594, __extension__ __PRETTY_FUNCTION__
))
;
1595 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1596 const DSAInfo &Data = I->SharingMap.lookup(D);
1597 if (Data.Attributes != OMPC_reduction ||
1598 Data.Modifier != OMPC_REDUCTION_task)
1599 continue;
1600 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1601 if (!ReductionData.ReductionOp ||
1602 ReductionData.ReductionOp.is<const Expr *>())
1603 return DSAVarData();
1604 SR = ReductionData.ReductionRange;
1605 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1606 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", 1608, __extension__ __PRETTY_FUNCTION__
))
1607 "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", 1608, __extension__ __PRETTY_FUNCTION__
))
1608 "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", 1608, __extension__ __PRETTY_FUNCTION__
))
;
1609 TaskgroupDescriptor = I->TaskgroupReductionRef;
1610 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1611 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1612 /*AppliedToPointee=*/false);
1613 }
1614 return DSAVarData();
1615}
1616
1617const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1618 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1619 Expr *&TaskgroupDescriptor) const {
1620 D = getCanonicalDecl(D);
1621 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", 1621, __extension__ __PRETTY_FUNCTION__
))
;
1622 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1623 const DSAInfo &Data = I->SharingMap.lookup(D);
1624 if (Data.Attributes != OMPC_reduction ||
1625 Data.Modifier != OMPC_REDUCTION_task)
1626 continue;
1627 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1628 if (!ReductionData.ReductionOp ||
1629 !ReductionData.ReductionOp.is<const Expr *>())
1630 return DSAVarData();
1631 SR = ReductionData.ReductionRange;
1632 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1633 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", 1635, __extension__ __PRETTY_FUNCTION__
))
1634 "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", 1635, __extension__ __PRETTY_FUNCTION__
))
1635 "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", 1635, __extension__ __PRETTY_FUNCTION__
))
;
1636 TaskgroupDescriptor = I->TaskgroupReductionRef;
1637 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1638 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1639 /*AppliedToPointee=*/false);
1640 }
1641 return DSAVarData();
1642}
1643
1644bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1645 D = D->getCanonicalDecl();
1646 for (const_iterator E = end(); I != E; ++I) {
1647 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1648 isOpenMPTargetExecutionDirective(I->Directive)) {
1649 if (I->CurScope) {
1650 Scope *TopScope = I->CurScope->getParent();
1651 Scope *CurScope = getCurScope();
1652 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1653 CurScope = CurScope->getParent();
1654 return CurScope != TopScope;
1655 }
1656 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1657 if (I->Context == DC)
1658 return true;
1659 return false;
1660 }
1661 }
1662 return false;
1663}
1664
1665static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1666 bool AcceptIfMutable = true,
1667 bool *IsClassType = nullptr) {
1668 ASTContext &Context = SemaRef.getASTContext();
1669 Type = Type.getNonReferenceType().getCanonicalType();
1670 bool IsConstant = Type.isConstant(Context);
1671 Type = Context.getBaseElementType(Type);
1672 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1673 ? Type->getAsCXXRecordDecl()
1674 : nullptr;
1675 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1676 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1677 RD = CTD->getTemplatedDecl();
1678 if (IsClassType)
1679 *IsClassType = RD;
1680 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1681 RD->hasDefinition() && RD->hasMutableFields());
1682}
1683
1684static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1685 QualType Type, OpenMPClauseKind CKind,
1686 SourceLocation ELoc,
1687 bool AcceptIfMutable = true,
1688 bool ListItemNotVar = false) {
1689 ASTContext &Context = SemaRef.getASTContext();
1690 bool IsClassType;
1691 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1692 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1693 : IsClassType ? diag::err_omp_const_not_mutable_variable
1694 : diag::err_omp_const_variable;
1695 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1696 if (!ListItemNotVar && D) {
1697 const VarDecl *VD = dyn_cast<VarDecl>(D);
1698 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1699 VarDecl::DeclarationOnly;
1700 SemaRef.Diag(D->getLocation(),
1701 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1702 << D;
1703 }
1704 return true;
1705 }
1706 return false;
1707}
1708
1709const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1710 bool FromParent) {
1711 D = getCanonicalDecl(D);
1712 DSAVarData DVar;
1713
1714 auto *VD = dyn_cast<VarDecl>(D);
1715 auto TI = Threadprivates.find(D);
1716 if (TI != Threadprivates.end()) {
1717 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1718 DVar.CKind = OMPC_threadprivate;
1719 DVar.Modifier = TI->getSecond().Modifier;
1720 return DVar;
1721 }
1722 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1723 DVar.RefExpr = buildDeclRefExpr(
1724 SemaRef, VD, D->getType().getNonReferenceType(),
1725 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1726 DVar.CKind = OMPC_threadprivate;
1727 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1728 return DVar;
1729 }
1730 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1731 // in a Construct, C/C++, predetermined, p.1]
1732 // Variables appearing in threadprivate directives are threadprivate.
1733 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1734 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1735 SemaRef.getLangOpts().OpenMPUseTLS &&
1736 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1737 (VD && VD->getStorageClass() == SC_Register &&
1738 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1739 DVar.RefExpr = buildDeclRefExpr(
1740 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1741 DVar.CKind = OMPC_threadprivate;
1742 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1743 return DVar;
1744 }
1745 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1746 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1747 !isLoopControlVariable(D).first) {
1748 const_iterator IterTarget =
1749 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1750 return isOpenMPTargetExecutionDirective(Data.Directive);
1751 });
1752 if (IterTarget != end()) {
1753 const_iterator ParentIterTarget = IterTarget + 1;
1754 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1755 if (isOpenMPLocal(VD, Iter)) {
1756 DVar.RefExpr =
1757 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1758 D->getLocation());
1759 DVar.CKind = OMPC_threadprivate;
1760 return DVar;
1761 }
1762 }
1763 if (!isClauseParsingMode() || IterTarget != begin()) {
1764 auto DSAIter = IterTarget->SharingMap.find(D);
1765 if (DSAIter != IterTarget->SharingMap.end() &&
1766 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1767 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1768 DVar.CKind = OMPC_threadprivate;
1769 return DVar;
1770 }
1771 const_iterator End = end();
1772 if (!SemaRef.isOpenMPCapturedByRef(D,
1773 std::distance(ParentIterTarget, End),
1774 /*OpenMPCaptureLevel=*/0)) {
1775 DVar.RefExpr =
1776 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1777 IterTarget->ConstructLoc);
1778 DVar.CKind = OMPC_threadprivate;
1779 return DVar;
1780 }
1781 }
1782 }
1783 }
1784
1785 if (isStackEmpty())
1786 // Not in OpenMP execution region and top scope was already checked.
1787 return DVar;
1788
1789 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1790 // in a Construct, C/C++, predetermined, p.4]
1791 // Static data members are shared.
1792 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1793 // in a Construct, C/C++, predetermined, p.7]
1794 // Variables with static storage duration that are declared in a scope
1795 // inside the construct are shared.
1796 if (VD && VD->isStaticDataMember()) {
1797 // Check for explicitly specified attributes.
1798 const_iterator I = begin();
1799 const_iterator EndI = end();
1800 if (FromParent && I != EndI)
1801 ++I;
1802 if (I != EndI) {
1803 auto It = I->SharingMap.find(D);
1804 if (It != I->SharingMap.end()) {
1805 const DSAInfo &Data = It->getSecond();
1806 DVar.RefExpr = Data.RefExpr.getPointer();
1807 DVar.PrivateCopy = Data.PrivateCopy;
1808 DVar.CKind = Data.Attributes;
1809 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1810 DVar.DKind = I->Directive;
1811 DVar.Modifier = Data.Modifier;
1812 DVar.AppliedToPointee = Data.AppliedToPointee;
1813 return DVar;
1814 }
1815 }
1816
1817 DVar.CKind = OMPC_shared;
1818 return DVar;
1819 }
1820
1821 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1822 // The predetermined shared attribute for const-qualified types having no
1823 // mutable members was removed after OpenMP 3.1.
1824 if (SemaRef.LangOpts.OpenMP <= 31) {
1825 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1826 // in a Construct, C/C++, predetermined, p.6]
1827 // Variables with const qualified type having no mutable member are
1828 // shared.
1829 if (isConstNotMutableType(SemaRef, D->getType())) {
1830 // Variables with const-qualified type having no mutable member may be
1831 // listed in a firstprivate clause, even if they are static data members.
1832 DSAVarData DVarTemp = hasInnermostDSA(
1833 D,
1834 [](OpenMPClauseKind C, bool) {
1835 return C == OMPC_firstprivate || C == OMPC_shared;
1836 },
1837 MatchesAlways, FromParent);
1838 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1839 return DVarTemp;
1840
1841 DVar.CKind = OMPC_shared;
1842 return DVar;
1843 }
1844 }
1845
1846 // Explicitly specified attributes and local variables with predetermined
1847 // attributes.
1848 const_iterator I = begin();
1849 const_iterator EndI = end();
1850 if (FromParent && I != EndI)
1851 ++I;
1852 if (I == EndI)
1853 return DVar;
1854 auto It = I->SharingMap.find(D);
1855 if (It != I->SharingMap.end()) {
1856 const DSAInfo &Data = It->getSecond();
1857 DVar.RefExpr = Data.RefExpr.getPointer();
1858 DVar.PrivateCopy = Data.PrivateCopy;
1859 DVar.CKind = Data.Attributes;
1860 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1861 DVar.DKind = I->Directive;
1862 DVar.Modifier = Data.Modifier;
1863 DVar.AppliedToPointee = Data.AppliedToPointee;
1864 }
1865
1866 return DVar;
1867}
1868
1869const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1870 bool FromParent) const {
1871 if (isStackEmpty()) {
1872 const_iterator I;
1873 return getDSA(I, D);
1874 }
1875 D = getCanonicalDecl(D);
1876 const_iterator StartI = begin();
1877 const_iterator EndI = end();
1878 if (FromParent && StartI != EndI)
1879 ++StartI;
1880 return getDSA(StartI, D);
1881}
1882
1883const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1884 unsigned Level) const {
1885 if (getStackSize() <= Level)
1886 return DSAVarData();
1887 D = getCanonicalDecl(D);
1888 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1889 return getDSA(StartI, D);
1890}
1891
1892const DSAStackTy::DSAVarData
1893DSAStackTy::hasDSA(ValueDecl *D,
1894 const llvm::function_ref<bool(OpenMPClauseKind, bool,
1895 DefaultDataSharingAttributes)>
1896 CPred,
1897 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1898 bool FromParent) const {
1899 if (isStackEmpty())
1900 return {};
1901 D = getCanonicalDecl(D);
1902 const_iterator I = begin();
1903 const_iterator EndI = end();
1904 if (FromParent && I != EndI)
1905 ++I;
1906 for (; I != EndI; ++I) {
1907 if (!DPred(I->Directive) &&
1908 !isImplicitOrExplicitTaskingRegion(I->Directive))
1909 continue;
1910 const_iterator NewI = I;
1911 DSAVarData DVar = getDSA(NewI, D);
1912 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1913 return DVar;
1914 }
1915 return {};
1916}
1917
1918const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1919 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1920 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1921 bool FromParent) const {
1922 if (isStackEmpty())
1923 return {};
1924 D = getCanonicalDecl(D);
1925 const_iterator StartI = begin();
1926 const_iterator EndI = end();
1927 if (FromParent && StartI != EndI)
1928 ++StartI;
1929 if (StartI == EndI || !DPred(StartI->Directive))
1930 return {};
1931 const_iterator NewI = StartI;
1932 DSAVarData DVar = getDSA(NewI, D);
1933 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1934 ? DVar
1935 : DSAVarData();
1936}
1937
1938bool DSAStackTy::hasExplicitDSA(
1939 const ValueDecl *D,
1940 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1941 unsigned Level, bool NotLastprivate) const {
1942 if (getStackSize() <= Level)
1943 return false;
1944 D = getCanonicalDecl(D);
1945 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1946 auto I = StackElem.SharingMap.find(D);
1947 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1948 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1949 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1950 return true;
1951 // Check predetermined rules for the loop control variables.
1952 auto LI = StackElem.LCVMap.find(D);
1953 if (LI != StackElem.LCVMap.end())
1954 return CPred(OMPC_private, /*AppliedToPointee=*/false);
1955 return false;
1956}
1957
1958bool DSAStackTy::hasExplicitDirective(
1959 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1960 unsigned Level) const {
1961 if (getStackSize() <= Level)
1962 return false;
1963 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1964 return DPred(StackElem.Directive);
1965}
1966
1967bool DSAStackTy::hasDirective(
1968 const llvm::function_ref<bool(OpenMPDirectiveKind,
1969 const DeclarationNameInfo &, SourceLocation)>
1970 DPred,
1971 bool FromParent) const {
1972 // We look only in the enclosing region.
1973 size_t Skip = FromParent ? 2 : 1;
1974 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1975 I != E; ++I) {
1976 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1977 return true;
1978 }
1979 return false;
1980}
1981
1982void Sema::InitDataSharingAttributesStack() {
1983 VarDataSharingAttributesStack = new DSAStackTy(*this);
1984}
1985
1986#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1987
1988void Sema::pushOpenMPFunctionRegion() { DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction(); }
1989
1990void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1991 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1992}
1993
1994static bool isOpenMPDeviceDelayedContext(Sema &S) {
1995 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", 1996, __extension__ __PRETTY_FUNCTION__
))
1996 "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", 1996, __extension__ __PRETTY_FUNCTION__
))
;
1997 return !S.isInOpenMPTargetExecutionDirective();
1998}
1999
2000namespace {
2001/// Status of the function emission on the host/device.
2002enum class FunctionEmissionStatus {
2003 Emitted,
2004 Discarded,
2005 Unknown,
2006};
2007} // anonymous namespace
2008
2009Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
2010 unsigned DiagID,
2011 FunctionDecl *FD) {
2012 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", 2013, __extension__ __PRETTY_FUNCTION__
))
2013 "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", 2013, __extension__ __PRETTY_FUNCTION__
))
;
2014
2015 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2016 if (FD) {
2017 FunctionEmissionStatus FES = getEmissionStatus(FD);
2018 switch (FES) {
2019 case FunctionEmissionStatus::Emitted:
2020 Kind = SemaDiagnosticBuilder::K_Immediate;
2021 break;
2022 case FunctionEmissionStatus::Unknown:
2023 // TODO: We should always delay diagnostics here in case a target
2024 // region is in a function we do not emit. However, as the
2025 // current diagnostics are associated with the function containing
2026 // the target region and we do not emit that one, we would miss out
2027 // on diagnostics for the target region itself. We need to anchor
2028 // the diagnostics with the new generated function *or* ensure we
2029 // emit diagnostics associated with the surrounding function.
2030 Kind = isOpenMPDeviceDelayedContext(*this)
2031 ? SemaDiagnosticBuilder::K_Deferred
2032 : SemaDiagnosticBuilder::K_Immediate;
2033 break;
2034 case FunctionEmissionStatus::TemplateDiscarded:
2035 case FunctionEmissionStatus::OMPDiscarded:
2036 Kind = SemaDiagnosticBuilder::K_Nop;
2037 break;
2038 case FunctionEmissionStatus::CUDADiscarded:
2039 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "clang/lib/Sema/SemaOpenMP.cpp", 2039)
;
2040 break;
2041 }
2042 }
2043
2044 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2045}
2046
2047Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2048 unsigned DiagID,
2049 FunctionDecl *FD) {
2050 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", 2051, __extension__ __PRETTY_FUNCTION__
))
2051 "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", 2051, __extension__ __PRETTY_FUNCTION__
))
;
2052
2053 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2054 if (FD) {
2055 FunctionEmissionStatus FES = getEmissionStatus(FD);
2056 switch (FES) {
2057 case FunctionEmissionStatus::Emitted:
2058 Kind = SemaDiagnosticBuilder::K_Immediate;
2059 break;
2060 case FunctionEmissionStatus::Unknown:
2061 Kind = SemaDiagnosticBuilder::K_Deferred;
2062 break;
2063 case FunctionEmissionStatus::TemplateDiscarded:
2064 case FunctionEmissionStatus::OMPDiscarded:
2065 case FunctionEmissionStatus::CUDADiscarded:
2066 Kind = SemaDiagnosticBuilder::K_Nop;
2067 break;
2068 }
2069 }
2070
2071 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2072}
2073
2074static OpenMPDefaultmapClauseKind
2075getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2076 if (LO.OpenMP <= 45) {
2077 if (VD->getType().getNonReferenceType()->isScalarType())
2078 return OMPC_DEFAULTMAP_scalar;
2079 return OMPC_DEFAULTMAP_aggregate;
2080 }
2081 if (VD->getType().getNonReferenceType()->isAnyPointerType())
2082 return OMPC_DEFAULTMAP_pointer;
2083 if (VD->getType().getNonReferenceType()->isScalarType())
2084 return OMPC_DEFAULTMAP_scalar;
2085 return OMPC_DEFAULTMAP_aggregate;
2086}
2087
2088bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2089 unsigned OpenMPCaptureLevel) const {
2090 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", 2090, __extension__ __PRETTY_FUNCTION__
))
;
2091
2092 ASTContext &Ctx = getASTContext();
2093 bool IsByRef = true;
2094
2095 // Find the directive that is associated with the provided scope.
2096 D = cast<ValueDecl>(D->getCanonicalDecl());
2097 QualType Ty = D->getType();
2098
2099 bool IsVariableUsedInMapClause = false;
2100 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2101 // This table summarizes how a given variable should be passed to the device
2102 // given its type and the clauses where it appears. This table is based on
2103 // the description in OpenMP 4.5 [2.10.4, target Construct] and
2104 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2105 //
2106 // =========================================================================
2107 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2108 // | |(tofrom:scalar)| | pvt | |has_dv_adr| |
2109 // =========================================================================
2110 // | scl | | | | - | | bycopy|
2111 // | scl | | - | x | - | - | bycopy|
2112 // | scl | | x | - | - | - | null |
2113 // | scl | x | | | - | | byref |
2114 // | scl | x | - | x | - | - | bycopy|
2115 // | scl | x | x | - | - | - | null |
2116 // | scl | | - | - | - | x | byref |
2117 // | scl | x | - | - | - | x | byref |
2118 //
2119 // | agg | n.a. | | | - | | byref |
2120 // | agg | n.a. | - | x | - | - | byref |
2121 // | agg | n.a. | x | - | - | - | null |
2122 // | agg | n.a. | - | - | - | x | byref |
2123 // | agg | n.a. | - | - | - | x[] | byref |
2124 //
2125 // | ptr | n.a. | | | - | | bycopy|
2126 // | ptr | n.a. | - | x | - | - | bycopy|
2127 // | ptr | n.a. | x | - | - | - | null |
2128 // | ptr | n.a. | - | - | - | x | byref |
2129 // | ptr | n.a. | - | - | - | x[] | bycopy|
2130 // | ptr | n.a. | - | - | x | | bycopy|
2131 // | ptr | n.a. | - | - | x | x | bycopy|
2132 // | ptr | n.a. | - | - | x | x[] | bycopy|
2133 // =========================================================================
2134 // Legend:
2135 // scl - scalar
2136 // ptr - pointer
2137 // agg - aggregate
2138 // x - applies
2139 // - - invalid in this combination
2140 // [] - mapped with an array section
2141 // byref - should be mapped by reference
2142 // byval - should be mapped by value
2143 // null - initialize a local variable to null on the device
2144 //
2145 // Observations:
2146 // - All scalar declarations that show up in a map clause have to be passed
2147 // by reference, because they may have been mapped in the enclosing data
2148 // environment.
2149 // - If the scalar value does not fit the size of uintptr, it has to be
2150 // passed by reference, regardless the result in the table above.
2151 // - For pointers mapped by value that have either an implicit map or an
2152 // array section, the runtime library may pass the NULL value to the
2153 // device instead of the value passed to it by the compiler.
2154
2155 if (Ty->isReferenceType())
2156 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2157
2158 // Locate map clauses and see if the variable being captured is referred to
2159 // in any of those clauses. Here we only care about variables, not fields,
2160 // because fields are part of aggregates.
2161 bool IsVariableAssociatedWithSection = false;
2162
2163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2164 D, Level,
2165 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2166 D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2167 MapExprComponents,
2168 OpenMPClauseKind WhereFoundClauseKind) {
2169 // Both map and has_device_addr clauses information influences how a
2170 // variable is captured. E.g. is_device_ptr does not require changing
2171 // the default behavior.
2172 if (WhereFoundClauseKind != OMPC_map &&
2173 WhereFoundClauseKind != OMPC_has_device_addr)
2174 return false;
2175
2176 auto EI = MapExprComponents.rbegin();
2177 auto EE = MapExprComponents.rend();
2178
2179 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", 2179, __extension__ __PRETTY_FUNCTION__
))
;
2180
2181 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2182 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2183
2184 ++EI;
2185 if (EI == EE)
2186 return false;
2187
2188 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2189 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2190 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2191 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2192 IsVariableAssociatedWithSection = true;
2193 // There is nothing more we need to know about this variable.
2194 return true;
2195 }
2196
2197 // Keep looking for more map info.
2198 return false;
2199 });
2200
2201 if (IsVariableUsedInMapClause) {
2202 // If variable is identified in a map clause it is always captured by
2203 // reference except if it is a pointer that is dereferenced somehow.
2204 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2205 } else {
2206 // By default, all the data that has a scalar type is mapped by copy
2207 // (except for reduction variables).
2208 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2209 IsByRef = (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2210 !Ty->isAnyPointerType()) ||
2211 !Ty->isScalarType() ||
2212 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2213 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2214 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2215 D,
2216 [](OpenMPClauseKind K, bool AppliedToPointee) {
2217 return K == OMPC_reduction && !AppliedToPointee;
2218 },
2219 Level);
2220 }
2221 }
2222
2223 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2224 IsByRef =
2225 ((IsVariableUsedInMapClause &&
2226 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2227 OMPD_target) ||
2228 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2229 D,
2230 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2231 return K == OMPC_firstprivate ||
2232 (K == OMPC_reduction && AppliedToPointee);
2233 },
2234 Level, /*NotLastprivate=*/true) ||
2235 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2236 // If the variable is artificial and must be captured by value - try to
2237 // capture by value.
2238 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2239 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2240 // If the variable is implicitly firstprivate and scalar - capture by
2241 // copy
2242 !((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate ||
2243 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_private) &&
2244 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2245 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2246 Level) &&
2247 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2248 }
2249
2250 // When passing data by copy, we need to make sure it fits the uintptr size
2251 // and alignment, because the runtime library only deals with uintptr types.
2252 // If it does not fit the uintptr size, we need to pass the data by reference
2253 // instead.
2254 if (!IsByRef &&
2255 (Ctx.getTypeSizeInChars(Ty) >
2256 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2257 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2258 IsByRef = true;
2259 }
2260
2261 return IsByRef;
2262}
2263
2264unsigned Sema::getOpenMPNestingLevel() const {
2265 assert(getLangOpts().OpenMP)(static_cast <bool> (getLangOpts().OpenMP) ? void (0) :
__assert_fail ("getLangOpts().OpenMP", "clang/lib/Sema/SemaOpenMP.cpp"
, 2265, __extension__ __PRETTY_FUNCTION__))
;
2266 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2267}
2268
2269bool Sema::isInOpenMPTaskUntiedContext() const {
2270 return isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2271 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUntiedRegion();
2272}
2273
2274bool Sema::isInOpenMPTargetExecutionDirective() const {
2275 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2276 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2277 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2278 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2279 SourceLocation) -> bool {
2280 return isOpenMPTargetExecutionDirective(K);
2281 },
2282 false);
2283}
2284
2285bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2286 // Only rebuild for Field.
2287 if (!dyn_cast<FieldDecl>(D))
2288 return false;
2289 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2290 D,
2291 [](OpenMPClauseKind C, bool AppliedToPointee,
2292 DefaultDataSharingAttributes DefaultAttr) {
2293 return isOpenMPPrivate(C) && !AppliedToPointee &&
2294 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2295 },
2296 [](OpenMPDirectiveKind) { return true; },
2297 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2298 if (DVarPrivate.CKind != OMPC_unknown)
2299 return true;
2300 return false;
2301}
2302
2303static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2304 Expr *CaptureExpr, bool WithInit,
2305 DeclContext *CurContext,
2306 bool AsExpression);
2307
2308VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2309 unsigned StopAt) {
2310 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", 2310, __extension__ __PRETTY_FUNCTION__
))
;
2311 D = getCanonicalDecl(D);
2312
2313 auto *VD = dyn_cast<VarDecl>(D);
2314 // Do not capture constexpr variables.
2315 if (VD && VD->isConstexpr())
2316 return nullptr;
2317
2318 // If we want to determine whether the variable should be captured from the
2319 // perspective of the current capturing scope, and we've already left all the
2320 // capturing scopes of the top directive on the stack, check from the
2321 // perspective of its parent directive (if any) instead.
2322 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2323 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2324
2325 // If we are attempting to capture a global variable in a directive with
2326 // 'target' we return true so that this global is also mapped to the device.
2327 //
2328 if (VD && !VD->hasLocalStorage() &&
2329 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2330 if (isInOpenMPTargetExecutionDirective()) {
2331 DSAStackTy::DSAVarData DVarTop =
2332 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2333 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2334 return VD;
2335 // If the declaration is enclosed in a 'declare target' directive,
2336 // then it should not be captured.
2337 //
2338 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2339 return nullptr;
2340 CapturedRegionScopeInfo *CSI = nullptr;
2341 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2342 llvm::reverse(FunctionScopes),
2343 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2344 if (!isa<CapturingScopeInfo>(FSI))
2345 return nullptr;
2346 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2347 if (RSI->CapRegionKind == CR_OpenMP) {
2348 CSI = RSI;
2349 break;
2350 }
2351 }
2352 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", 2352, __extension__ __PRETTY_FUNCTION__
))
;
2353 SmallVector<OpenMPDirectiveKind, 4> Regions;
2354 getOpenMPCaptureRegions(Regions,
2355 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2356 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2357 return VD;
2358 }
2359 if (isInOpenMPDeclareTargetContext()) {
2360 // Try to mark variable as declare target if it is used in capturing
2361 // regions.
2362 if (LangOpts.OpenMP <= 45 &&
2363 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2364 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2365 return nullptr;
2366 }
2367 }
2368
2369 if (CheckScopeInfo) {
2370 bool OpenMPFound = false;
2371 for (unsigned I = StopAt + 1; I > 0; --I) {
2372 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2373 if (!isa<CapturingScopeInfo>(FSI))
2374 return nullptr;
2375 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2376 if (RSI->CapRegionKind == CR_OpenMP) {
2377 OpenMPFound = true;
2378 break;
2379 }
2380 }
2381 if (!OpenMPFound)
2382 return nullptr;
2383 }
2384
2385 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2386 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2387 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2388 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2389 if (Info.first ||
2390 (VD && VD->hasLocalStorage() &&
2391 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2392 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2393 return VD ? VD : Info.second;
2394 DSAStackTy::DSAVarData DVarTop =
2395 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2396 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2397 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2398 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2399 // Threadprivate variables must not be captured.
2400 if (isOpenMPThreadPrivate(DVarTop.CKind))
2401 return nullptr;
2402 // The variable is not private or it is the variable in the directive with
2403 // default(none) clause and not used in any clause.
2404 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2405 D,
2406 [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2407 return isOpenMPPrivate(C) && !AppliedToPointee;
2408 },
2409 [](OpenMPDirectiveKind) { return true; },
2410 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2411 // Global shared must not be captured.
2412 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2413 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2414 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_private &&
2415 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2416 DVarTop.CKind == OMPC_shared))
2417 return nullptr;
2418 auto *FD = dyn_cast<FieldDecl>(D);
2419 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2420 !DVarPrivate.PrivateCopy) {
2421 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2422 D,
2423 [](OpenMPClauseKind C, bool AppliedToPointee,
2424 DefaultDataSharingAttributes DefaultAttr) {
2425 return isOpenMPPrivate(C) && !AppliedToPointee &&
2426 (DefaultAttr == DSA_firstprivate ||
2427 DefaultAttr == DSA_private);
2428 },
2429 [](OpenMPDirectiveKind) { return true; },
2430 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2431 if (DVarPrivate.CKind == OMPC_unknown)
2432 return nullptr;
2433
2434 VarDecl *VD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitFDCapExprDecl(FD);
2435 if (VD)
2436 return VD;
2437 if (getCurrentThisType().isNull())
2438 return nullptr;
2439 Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2440 /*IsImplicit=*/true);
2441 const CXXScopeSpec CS = CXXScopeSpec();
2442 Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2443 NestedNameSpecifierLoc(), SourceLocation(), FD,
2444 DeclAccessPair::make(FD, FD->getAccess()),
2445 /*HadMultipleCandidates=*/false,
2446 DeclarationNameInfo(), FD->getType(),
2447 VK_LValue, OK_Ordinary);
2448 OMPCapturedExprDecl *CD = buildCaptureDecl(
2449 *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2450 CurContext->getParent(), /*AsExpression=*/false);
2451 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2452 *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2453 VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2454 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitDefaultFirstprivateFD(FD, VD);
2455 return VD;
2456 }
2457 if (DVarPrivate.CKind != OMPC_unknown ||
2458 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2459 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_private ||
2460 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2461 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2462 }
2463 return nullptr;
2464}
2465
2466void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2467 unsigned Level) const {
2468 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2469}
2470
2471void Sema::startOpenMPLoop() {
2472 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", 2472, __extension__ __PRETTY_FUNCTION__
))
;
2473 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2474 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2475}
2476
2477void Sema::startOpenMPCXXRangeFor() {
2478 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", 2478, __extension__ __PRETTY_FUNCTION__
))
;
2479 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2480 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2481 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2482 }
2483}
2484
2485OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2486 unsigned CapLevel) const {
2487 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", 2487, __extension__ __PRETTY_FUNCTION__
))
;
2488 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2489 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2490 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2491 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2492 D,
2493 [](OpenMPClauseKind C, bool AppliedToPointee,
2494 DefaultDataSharingAttributes DefaultAttr) {
2495 return isOpenMPPrivate(C) && !AppliedToPointee &&
2496 DefaultAttr == DSA_private;
2497 },
2498 [](OpenMPDirectiveKind) { return true; },
2499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2500 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2501 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2502 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first)
2503 return OMPC_private;
2504 }
2505 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2506 bool IsTriviallyCopyable =
2507 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2508 !D->getType()
2509 .getNonReferenceType()
2510 .getCanonicalType()
2511 ->getAsCXXRecordDecl();
2512 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2513 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2514 getOpenMPCaptureRegions(CaptureRegions, DKind);
2515 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2516 (IsTriviallyCopyable ||
2517 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2518 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2519 D,
2520 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2521 Level, /*NotLastprivate=*/true))
2522 return OMPC_firstprivate;
2523 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2524 if (DVar.CKind != OMPC_shared &&
2525 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2526 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2527 return OMPC_firstprivate;
2528 }
2529 }
2530 }
2531 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2532 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2533 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2534 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2535 return OMPC_private;
2536 }
2537 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2538 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2539 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2540 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2541 Level) &&
2542 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2543 return OMPC_private;
2544 }
2545 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2546 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2547 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2548 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2549 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2550 Level))
2551 return OMPC_private;
2552 }
2553 // User-defined allocators are private since they must be defined in the
2554 // context of target region.
2555 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2556 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).value_or(
2557 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2558 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2559 return OMPC_private;
2560 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2561 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2562 Level) ||
2563 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2564 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2565 // Consider taskgroup reduction descriptor variable a private
2566 // to avoid possible capture in the region.
2567 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2568 [](OpenMPDirectiveKind K) {
2569 return K == OMPD_taskgroup ||
2570 ((isOpenMPParallelDirective(K) ||
2571 isOpenMPWorksharingDirective(K)) &&
2572 !isOpenMPSimdDirective(K));
2573 },
2574 Level) &&
2575 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2576 ? OMPC_private
2577 : OMPC_unknown;
2578}
2579
2580void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2581 unsigned Level) {
2582 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", 2582, __extension__ __PRETTY_FUNCTION__
))
;
2583 D = getCanonicalDecl(D);
2584 OpenMPClauseKind OMPC = OMPC_unknown;
2585 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2586 const unsigned NewLevel = I - 1;
2587 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2588 D,
2589 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2590 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2591 OMPC = K;
2592 return true;
2593 }
2594 return false;
2595 },
2596 NewLevel))
2597 break;
2598 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2599 D, NewLevel,
2600 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2601 OpenMPClauseKind) { return true; })) {
2602 OMPC = OMPC_map;
2603 break;
2604 }
2605 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2606 NewLevel)) {
2607 OMPC = OMPC_map;
2608 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2609 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2610 OMPC = OMPC_firstprivate;
2611 break;
2612 }
2613 }
2614 if (OMPC != OMPC_unknown)
2615 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2616}
2617
2618bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2619 unsigned CaptureLevel) const {
2620 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", 2620, __extension__ __PRETTY_FUNCTION__
))
;
2621 // Return true if the current level is no longer enclosed in a target region.
2622
2623 SmallVector<OpenMPDirectiveKind, 4> Regions;
2624 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2625 const auto *VD = dyn_cast<VarDecl>(D);
2626 return VD && !VD->hasLocalStorage() &&
2627 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2628 Level) &&
2629 Regions[CaptureLevel] != OMPD_task;
2630}
2631
2632bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2633 unsigned CaptureLevel) const {
2634 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", 2634, __extension__ __PRETTY_FUNCTION__
))
;
2635 // Return true if the current level is no longer enclosed in a target region.
2636
2637 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2638 if (!VD->hasLocalStorage()) {
2639 if (isInOpenMPTargetExecutionDirective())
2640 return true;
2641 DSAStackTy::DSAVarData TopDVar =
2642 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2643 unsigned NumLevels =
2644 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2645 if (Level == 0)
2646 // non-file scope static variale with default(firstprivate)
2647 // should be gloabal captured.
2648 return (NumLevels == CaptureLevel + 1 &&
2649 (TopDVar.CKind != OMPC_shared ||
2650 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate));
2651 do {
2652 --Level;
2653 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2654 if (DVar.CKind != OMPC_shared)
2655 return true;
2656 } while (Level > 0);
2657 }
2658 }
2659 return true;
2660}
2661
2662void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2663
2664void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2665 OMPTraitInfo &TI) {
2666 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2667}
2668
2669void Sema::ActOnOpenMPEndDeclareVariant() {
2670 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", 2671, __extension__ __PRETTY_FUNCTION__
))
2671 "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", 2671, __extension__ __PRETTY_FUNCTION__
))
;
2672
2673 OMPDeclareVariantScopes.pop_back();
2674}
2675
2676void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2677 const FunctionDecl *Callee,
2678 SourceLocation Loc) {
2679 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", 2679, __extension__ __PRETTY_FUNCTION__
))
;
2680 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2681 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2682 // Ignore host functions during device analyzis.
2683 if (LangOpts.OpenMPIsDevice &&
2684 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2685 return;
2686 // Ignore nohost functions during host analyzis.
2687 if (!LangOpts.OpenMPIsDevice && DevTy &&
2688 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2689 return;
2690 const FunctionDecl *FD = Callee->getMostRecentDecl();
2691 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2692 if (LangOpts.OpenMPIsDevice && DevTy &&
2693 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2694 // Diagnose host function called during device codegen.
2695 StringRef HostDevTy =
2696 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2697 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2698 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2699 diag::note_omp_marked_device_type_here)
2700 << HostDevTy;
2701 return;
2702 }
2703 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2704 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2705 // In OpenMP 5.2 or later, if the function has a host variant then allow
2706 // that to be called instead
2707 auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2708 for (OMPDeclareVariantAttr *A :
2709 Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2710 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2711 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2712 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2713 OMPDeclareTargetDeclAttr::getDeviceType(
2714 VariantFD->getMostRecentDecl());
2715 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2716 return true;
2717 }
2718 return false;
2719 };
2720 if (getLangOpts().OpenMP >= 52 &&
2721 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2722 return;
2723 // Diagnose nohost function called during host codegen.
2724 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2725 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2726 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2727 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2728 diag::note_omp_marked_device_type_here)
2729 << NoHostDevTy;
2730 }
2731}
2732
2733void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2734 const DeclarationNameInfo &DirName,
2735 Scope *CurScope, SourceLocation Loc) {
2736 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2737 PushExpressionEvaluationContext(
2738 ExpressionEvaluationContext::PotentiallyEvaluated);
2739}
2740
2741void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2742 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2743}
2744
2745void Sema::EndOpenMPClause() {
2746 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2747 CleanupVarDeclMarking();
2748}
2749
2750static std::pair<ValueDecl *, bool>
2751getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2752 SourceRange &ERange, bool AllowArraySection = false,
2753 StringRef DiagType = "");
2754
2755/// Check consistency of the reduction clauses.
2756static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2757 ArrayRef<OMPClause *> Clauses) {
2758 bool InscanFound = false;
2759 SourceLocation InscanLoc;
2760 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2761 // A reduction clause without the inscan reduction-modifier may not appear on
2762 // a construct on which a reduction clause with the inscan reduction-modifier
2763 // appears.
2764 for (OMPClause *C : Clauses) {
2765 if (C->getClauseKind() != OMPC_reduction)
2766 continue;
2767 auto *RC = cast<OMPReductionClause>(C);
2768 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2769 InscanFound = true;
2770 InscanLoc = RC->getModifierLoc();
2771 continue;
2772 }
2773 if (RC->getModifier() == OMPC_REDUCTION_task) {
2774 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2775 // A reduction clause with the task reduction-modifier may only appear on
2776 // a parallel construct, a worksharing construct or a combined or
2777 // composite construct for which any of the aforementioned constructs is a
2778 // constituent construct and simd or loop are not constituent constructs.
2779 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2780 if (!(isOpenMPParallelDirective(CurDir) ||
2781 isOpenMPWorksharingDirective(CurDir)) ||
2782 isOpenMPSimdDirective(CurDir))
2783 S.Diag(RC->getModifierLoc(),
2784 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2785 continue;
2786 }
2787 }
2788 if (InscanFound) {
2789 for (OMPClause *C : Clauses) {
2790 if (C->getClauseKind() != OMPC_reduction)
2791 continue;
2792 auto *RC = cast<OMPReductionClause>(C);
2793 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2794 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2795 ? RC->getBeginLoc()
2796 : RC->getModifierLoc(),
2797 diag::err_omp_inscan_reduction_expected);
2798 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2799 continue;
2800 }
2801 for (Expr *Ref : RC->varlists()) {
2802 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", 2802, __extension__ __PRETTY_FUNCTION__
))
;
2803 SourceLocation ELoc;
2804 SourceRange ERange;
2805 Expr *SimpleRefExpr = Ref;
2806 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2807 /*AllowArraySection=*/true);
2808 ValueDecl *D = Res.first;
2809 if (!D)
2810 continue;
2811 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2812 S.Diag(Ref->getExprLoc(),
2813 diag::err_omp_reduction_not_inclusive_exclusive)
2814 << Ref->getSourceRange();
2815 }
2816 }
2817 }
2818 }
2819}
2820
2821static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2822 ArrayRef<OMPClause *> Clauses);
2823static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2824 bool WithInit);
2825
2826static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2827 const ValueDecl *D,
2828 const DSAStackTy::DSAVarData &DVar,
2829 bool IsLoopIterVar = false);
2830
2831void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2832 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2833 // A variable of class type (or array thereof) that appears in a lastprivate
2834 // clause requires an accessible, unambiguous default constructor for the
2835 // class type, unless the list item is also specified in a firstprivate
2836 // clause.
2837 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2838 for (OMPClause *C : D->clauses()) {
2839 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2840 SmallVector<Expr *, 8> PrivateCopies;
2841 for (Expr *DE : Clause->varlists()) {
2842 if (DE->isValueDependent() || DE->isTypeDependent()) {
2843 PrivateCopies.push_back(nullptr);
2844 continue;
2845 }
2846 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2847 auto *VD = cast<VarDecl>(DRE->getDecl());
2848 QualType Type = VD->getType().getNonReferenceType();
2849 const DSAStackTy::DSAVarData DVar =
2850 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2851 if (DVar.CKind == OMPC_lastprivate) {
2852 // Generate helper private variable and initialize it with the
2853 // default value. The address of the original variable is replaced
2854 // by the address of the new private variable in CodeGen. This new
2855 // variable is not added to IdResolver, so the code in the OpenMP
2856 // region uses original variable for proper diagnostics.
2857 VarDecl *VDPrivate = buildVarDecl(
2858 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2859 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2860 ActOnUninitializedDecl(VDPrivate);
2861 if (VDPrivate->isInvalidDecl()) {
2862 PrivateCopies.push_back(nullptr);
2863 continue;
2864 }
2865 PrivateCopies.push_back(buildDeclRefExpr(
2866 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2867 } else {
2868 // The variable is also a firstprivate, so initialization sequence
2869 // for private copy is generated already.
2870 PrivateCopies.push_back(nullptr);
2871 }
2872 }
2873 Clause->setPrivateCopies(PrivateCopies);
2874 continue;
2875 }
2876 // Finalize nontemporal clause by handling private copies, if any.
2877 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2878 SmallVector<Expr *, 8> PrivateRefs;
2879 for (Expr *RefExpr : Clause->varlists()) {
2880 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", 2880, __extension__ __PRETTY_FUNCTION__
))
;
2881 SourceLocation ELoc;
2882 SourceRange ERange;
2883 Expr *SimpleRefExpr = RefExpr;
2884 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2885 if (Res.second)
2886 // It will be analyzed later.
2887 PrivateRefs.push_back(RefExpr);
2888 ValueDecl *D = Res.first;
2889 if (!D)
2890 continue;
2891
2892 const DSAStackTy::DSAVarData DVar =
2893 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2894 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2895 : SimpleRefExpr);
2896 }
2897 Clause->setPrivateRefs(PrivateRefs);
2898 continue;
2899 }
2900 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2901 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2902 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2903 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2904 if (!DRE)
2905 continue;
2906 ValueDecl *VD = DRE->getDecl();
2907 if (!VD || !isa<VarDecl>(VD))
2908 continue;
2909 DSAStackTy::DSAVarData DVar =
2910 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2911 // OpenMP [2.12.5, target Construct]
2912 // Memory allocators that appear in a uses_allocators clause cannot
2913 // appear in other data-sharing attribute clauses or data-mapping
2914 // attribute clauses in the same construct.
2915 Expr *MapExpr = nullptr;
2916 if (DVar.RefExpr ||
2917 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2918 VD, /*CurrentRegionOnly=*/true,
2919 [VD, &MapExpr](
2920 OMPClauseMappableExprCommon::MappableExprComponentListRef
2921 MapExprComponents,
2922 OpenMPClauseKind C) {
2923 auto MI = MapExprComponents.rbegin();
2924 auto ME = MapExprComponents.rend();
2925 if (MI != ME &&
2926 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2927 VD->getCanonicalDecl()) {
2928 MapExpr = MI->getAssociatedExpression();
2929 return true;
2930 }
2931 return false;
2932 })) {
2933 Diag(D.Allocator->getExprLoc(),
2934 diag::err_omp_allocator_used_in_clauses)
2935 << D.Allocator->getSourceRange();
2936 if (DVar.RefExpr)
2937 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2938 else
2939 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2940 << MapExpr->getSourceRange();
2941 }
2942 }
2943 continue;
2944 }
2945 }
2946 // Check allocate clauses.
2947 if (!CurContext->isDependentContext())
2948 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2949 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2950 }
2951
2952 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2953 DiscardCleanupsInEvaluationContext();
2954 PopExpressionEvaluationContext();
2955}
2956
2957static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2958 Expr *NumIterations, Sema &SemaRef,
2959 Scope *S, DSAStackTy *Stack);
2960
2961namespace {
2962
2963class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2964private:
2965 Sema &SemaRef;
2966
2967public:
2968 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2969 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2970 NamedDecl *ND = Candidate.getCorrectionDecl();
2971 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2972 return VD->hasGlobalStorage() &&
2973 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2974 SemaRef.getCurScope());
2975 }
2976 return false;
2977 }
2978
2979 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2980 return std::make_unique<VarDeclFilterCCC>(*this);
2981 }
2982};
2983
2984class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2985private:
2986 Sema &SemaRef;
2987
2988public:
2989 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2990 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2991 NamedDecl *ND = Candidate.getCorrectionDecl();
2992 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2993 isa<FunctionDecl>(ND))) {
2994 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2995 SemaRef.getCurScope());
2996 }
2997 return false;
2998 }
2999
3000 std::unique_ptr<CorrectionCandidateCallback> clone() override {
3001 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3002 }
3003};
3004
3005} // namespace
3006
3007ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3008 CXXScopeSpec &ScopeSpec,
3009 const DeclarationNameInfo &Id,
3010 OpenMPDirectiveKind Kind) {
3011 LookupResult Lookup(*this, Id, LookupOrdinaryName);
3012 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3013
3014 if (Lookup.isAmbiguous())
3015 return ExprError();
3016
3017 VarDecl *VD;
3018 if (!Lookup.isSingleResult()) {
3019 VarDeclFilterCCC CCC(*this);
3020 if (TypoCorrection Corrected =
3021 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3022 CTK_ErrorRecovery)) {
3023 diagnoseTypo(Corrected,
3024 PDiag(Lookup.empty()
3025 ? diag::err_undeclared_var_use_suggest
3026 : diag::err_omp_expected_var_arg_suggest)
3027 << Id.getName());
3028 VD = Corrected.getCorrectionDeclAs<VarDecl>();
3029 } else {
3030 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3031 : diag::err_omp_expected_var_arg)
3032 << Id.getName();
3033 return ExprError();
3034 }
3035 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3036 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3037 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3038 return ExprError();
3039 }
3040 Lookup.suppressDiagnostics();
3041
3042 // OpenMP [2.9.2, Syntax, C/C++]
3043 // Variables must be file-scope, namespace-scope, or static block-scope.
3044 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3045 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3046 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3047 bool IsDecl =
3048 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3049 Diag(VD->getLocation(),
3050 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3051 << VD;
3052 return ExprError();
3053 }
3054
3055 VarDecl *CanonicalVD = VD->getCanonicalDecl();
3056 NamedDecl *ND = CanonicalVD;
3057 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3058 // A threadprivate directive for file-scope variables must appear outside
3059 // any definition or declaration.
3060 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3061 !getCurLexicalContext()->isTranslationUnit()) {
3062 Diag(Id.getLoc(), diag::err_omp_var_scope)
3063 << getOpenMPDirectiveName(Kind) << VD;
3064 bool IsDecl =
3065 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3066 Diag(VD->getLocation(),
3067 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3068 << VD;
3069 return ExprError();
3070 }
3071 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3072 // A threadprivate directive for static class member variables must appear
3073 // in the class definition, in the same scope in which the member
3074 // variables are declared.
3075 if (CanonicalVD->isStaticDataMember() &&
3076 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3077 Diag(Id.getLoc(), diag::err_omp_var_scope)
3078 << getOpenMPDirectiveName(Kind) << VD;
3079 bool IsDecl =
3080 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3081 Diag(VD->getLocation(),
3082 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3083 << VD;
3084 return ExprError();
3085 }
3086 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3087 // A threadprivate directive for namespace-scope variables must appear
3088 // outside any definition or declaration other than the namespace
3089 // definition itself.
3090 if (CanonicalVD->getDeclContext()->isNamespace() &&
3091 (!getCurLexicalContext()->isFileContext() ||
3092 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3093 Diag(Id.getLoc(), diag::err_omp_var_scope)
3094 << getOpenMPDirectiveName(Kind) << VD;
3095 bool IsDecl =
3096 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3097 Diag(VD->getLocation(),
3098 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3099 << VD;
3100 return ExprError();
3101 }
3102 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3103 // A threadprivate directive for static block-scope variables must appear
3104 // in the scope of the variable and not in a nested scope.
3105 if (CanonicalVD->isLocalVarDecl() && CurScope &&
3106 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3107 Diag(Id.getLoc(), diag::err_omp_var_scope)
3108 << getOpenMPDirectiveName(Kind) << VD;
3109 bool IsDecl =
3110 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3111 Diag(VD->getLocation(),
3112 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3113 << VD;
3114 return ExprError();
3115 }
3116
3117 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3118 // A threadprivate directive must lexically precede all references to any
3119 // of the variables in its list.
3120 if (Kind == OMPD_threadprivate && VD->isUsed() &&
3121 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
3122 Diag(Id.getLoc(), diag::err_omp_var_used)
3123 << getOpenMPDirectiveName(Kind) << VD;
3124 return ExprError();
3125 }
3126
3127 QualType ExprType = VD->getType().getNonReferenceType();
3128 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3129 SourceLocation(), VD,
3130 /*RefersToEnclosingVariableOrCapture=*/false,
3131 Id.getLoc(), ExprType, VK_LValue);
3132}
3133
3134Sema::DeclGroupPtrTy
3135Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3136 ArrayRef<Expr *> VarList) {
3137 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3138 CurContext->addDecl(D);
3139 return DeclGroupPtrTy::make(DeclGroupRef(D));
3140 }
3141 return nullptr;
3142}
3143
3144namespace {
3145class LocalVarRefChecker final
3146 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3147 Sema &SemaRef;
3148
3149public:
3150 bool VisitDeclRefExpr(const DeclRefExpr *E) {
3151 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3152 if (VD->hasLocalStorage()) {
3153 SemaRef.Diag(E->getBeginLoc(),
3154 diag::err_omp_local_var_in_threadprivate_init)
3155 << E->getSourceRange();
3156 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3157 << VD << VD->getSourceRange();
3158 return true;
3159 }
3160 }
3161 return false;
3162 }
3163 bool VisitStmt(const Stmt *S) {
3164 for (const Stmt *Child : S->children()) {
3165 if (Child && Visit(Child))
3166 return true;
3167 }
3168 return false;
3169 }
3170 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3171};
3172} // namespace
3173
3174OMPThreadPrivateDecl *
3175Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3176 SmallVector<Expr *, 8> Vars;
3177 for (Expr *RefExpr : VarList) {
3178 auto *DE = cast<DeclRefExpr>(RefExpr);
3179 auto *VD = cast<VarDecl>(DE->getDecl());
3180 SourceLocation ILoc = DE->getExprLoc();
3181
3182 // Mark variable as used.
3183 VD->setReferenced();
3184 VD->markUsed(Context);
3185
3186 QualType QType = VD->getType();
3187 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3188 // It will be analyzed later.
3189 Vars.push_back(DE);
3190 continue;
3191 }
3192
3193 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3194 // A threadprivate variable must not have an incomplete type.
3195 if (RequireCompleteType(ILoc, VD->getType(),
3196 diag::err_omp_threadprivate_incomplete_type)) {
3197 continue;
3198 }
3199
3200 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3201 // A threadprivate variable must not have a reference type.
3202 if (VD->getType()->isReferenceType()) {
3203 Diag(ILoc, diag::err_omp_ref_type_arg)
3204 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3205 bool IsDecl =
3206 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3207 Diag(VD->getLocation(),
3208 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3209 << VD;
3210 continue;
3211 }
3212
3213 // Check if this is a TLS variable. If TLS is not being supported, produce
3214 // the corresponding diagnostic.
3215 if ((VD->getTLSKind() != VarDecl::TLS_None &&
3216 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3217 getLangOpts().OpenMPUseTLS &&
3218 getASTContext().getTargetInfo().isTLSSupported())) ||
3219 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3220 !VD->isLocalVarDecl())) {
3221 Diag(ILoc, diag::err_omp_var_thread_local)
3222 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3223 bool IsDecl =
3224 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3225 Diag(VD->getLocation(),
3226 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3227 << VD;
3228 continue;
3229 }
3230
3231 // Check if initial value of threadprivate variable reference variable with
3232 // local storage (it is not supported by runtime).
3233 if (const Expr *Init = VD->getAnyInitializer()) {
3234 LocalVarRefChecker Checker(*this);
3235 if (Checker.Visit(Init))
3236 continue;
3237 }
3238
3239 Vars.push_back(RefExpr);
3240 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
3241 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3242 Context, SourceRange(Loc, Loc)));
3243 if (ASTMutationListener *ML = Context.getASTMutationListener())
3244 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3245 }
3246 OMPThreadPrivateDecl *D = nullptr;
3247 if (!Vars.empty()) {
3248 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3249 Vars);
3250 D->setAccess(AS_public);
3251 }
3252 return D;
3253}
3254
3255static OMPAllocateDeclAttr::AllocatorTypeTy
3256getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3257 if (!Allocator)
3258 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3259 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3260 Allocator->isInstantiationDependent() ||
3261 Allocator->containsUnexpandedParameterPack())
3262 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3263 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3264 const Expr *AE = Allocator->IgnoreParenImpCasts();
3265 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3266 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3267 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3268 llvm::FoldingSetNodeID AEId, DAEId;
3269 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3270 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3271 if (AEId == DAEId) {
3272 AllocatorKindRes = AllocatorKind;
3273 break;
3274 }
3275 }
3276 return AllocatorKindRes;
3277}
3278
3279static bool checkPreviousOMPAllocateAttribute(
3280 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3281 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3282 if (!VD->hasAttr<OMPAllocateDeclAttr>())
3283 return false;
3284 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3285 Expr *PrevAllocator = A->getAllocator();
3286 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3287 getAllocatorKind(S, Stack, PrevAllocator);
3288 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3289 if (AllocatorsMatch &&
3290 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3291 Allocator && PrevAllocator) {
3292 const Expr *AE = Allocator->IgnoreParenImpCasts();
3293 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3294 llvm::FoldingSetNodeID AEId, PAEId;
3295 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3296 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3297 AllocatorsMatch = AEId == PAEId;
3298 }
3299 if (!AllocatorsMatch) {
3300 SmallString<256> AllocatorBuffer;
3301 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3302 if (Allocator)
3303 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3304 SmallString<256> PrevAllocatorBuffer;
3305 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3306 if (PrevAllocator)
3307 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3308 S.getPrintingPolicy());
3309
3310 SourceLocation AllocatorLoc =
3311 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3312 SourceRange AllocatorRange =
3313 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3314 SourceLocation PrevAllocatorLoc =
3315 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3316 SourceRange PrevAllocatorRange =
3317 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3318 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3319 << (Allocator ? 1 : 0) << AllocatorStream.str()
3320 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3321 << AllocatorRange;
3322 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3323 << PrevAllocatorRange;
3324 return true;
3325 }
3326 return false;
3327}
3328
3329static void
3330applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3331 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3332 Expr *Allocator, Expr *Alignment, SourceRange SR) {
3333 if (VD->hasAttr<OMPAllocateDeclAttr>())
3334 return;
3335 if (Alignment &&
3336 (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3337 Alignment->isInstantiationDependent() ||
3338 Alignment->containsUnexpandedParameterPack()))
3339 // Apply later when we have a usable value.
3340 return;
3341 if (Allocator &&
3342 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3343 Allocator->isInstantiationDependent() ||
3344 Allocator->containsUnexpandedParameterPack()))
3345 return;
3346 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3347 Allocator, Alignment, SR);
3348 VD->addAttr(A);
3349 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3350 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3351}
3352
3353Sema::DeclGroupPtrTy
3354Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3355 ArrayRef<OMPClause *> Clauses,
3356 DeclContext *Owner) {
3357 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", 3357, __extension__ __PRETTY_FUNCTION__
))
;
3358 Expr *Alignment = nullptr;
3359 Expr *Allocator = nullptr;
3360 if (Clauses.empty()) {
3361 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3362 // allocate directives that appear in a target region must specify an
3363 // allocator clause unless a requires directive with the dynamic_allocators
3364 // clause is present in the same compilation unit.
3365 if (LangOpts.OpenMPIsDevice &&
3366 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3367 targetDiag(Loc, diag::err_expected_allocator_clause);
3368 } else {
3369 for (const OMPClause *C : Clauses)
3370 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3371 Allocator = AC->getAllocator();
3372 else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3373 Alignment = AC->getAlignment();
3374 else
3375 llvm_unreachable("Unexpected clause on allocate directive")::llvm::llvm_unreachable_internal("Unexpected clause on allocate directive"
, "clang/lib/Sema/SemaOpenMP.cpp", 3375)
;
3376 }
3377 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3378 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3379 SmallVector<Expr *, 8> Vars;
3380 for (Expr *RefExpr : VarList) {
3381 auto *DE = cast<DeclRefExpr>(RefExpr);
3382 auto *VD = cast<VarDecl>(DE->getDecl());
3383
3384 // Check if this is a TLS variable or global register.
3385 if (VD->getTLSKind() != VarDecl::TLS_None ||
3386 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3387 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3388 !VD->isLocalVarDecl()))
3389 continue;
3390
3391 // If the used several times in the allocate directive, the same allocator
3392 // must be used.
3393 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3394 AllocatorKind, Allocator))
3395 continue;
3396
3397 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3398 // If a list item has a static storage type, the allocator expression in the
3399 // allocator clause must be a constant expression that evaluates to one of
3400 // the predefined memory allocator values.
3401 if (Allocator && VD->hasGlobalStorage()) {
3402 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3403 Diag(Allocator->getExprLoc(),
3404 diag::err_omp_expected_predefined_allocator)
3405 << Allocator->getSourceRange();
3406 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3407 VarDecl::DeclarationOnly;
3408 Diag(VD->getLocation(),
3409 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3410 << VD;
3411 continue;
3412 }
3413 }
3414
3415 Vars.push_back(RefExpr);
3416 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3417 DE->getSourceRange());
3418 }
3419 if (Vars.empty())
3420 return nullptr;
3421 if (!Owner)
3422 Owner = getCurLexicalContext();
3423 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3424 D->setAccess(AS_public);
3425 Owner->addDecl(D);
3426 return DeclGroupPtrTy::make(DeclGroupRef(D));
3427}
3428
3429Sema::DeclGroupPtrTy
3430Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3431 ArrayRef<OMPClause *> ClauseList) {
3432 OMPRequiresDecl *D = nullptr;
3433 if (!CurContext->isFileContext()) {
3434 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3435 } else {
3436 D = CheckOMPRequiresDecl(Loc, ClauseList);
3437 if (D) {
3438 CurContext->addDecl(D);
3439 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3440 }
3441 }
3442 return DeclGroupPtrTy::make(DeclGroupRef(D));
3443}
3444
3445void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3446 OpenMPDirectiveKind DKind,
3447 ArrayRef<std::string> Assumptions,
3448 bool SkippedClauses) {
3449 if (!SkippedClauses && Assumptions.empty())
3450 Diag(Loc, diag::err_omp_no_clause_for_directive)
3451 << llvm::omp::getAllAssumeClauseOptions()
3452 << llvm::omp::getOpenMPDirectiveName(DKind);
3453
3454 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3455 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3456 OMPAssumeScoped.push_back(AA);
3457 return;
3458 }
3459
3460 // Global assumes without assumption clauses are ignored.
3461 if (Assumptions.empty())
3462 return;
3463
3464 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", 3465, __extension__ __PRETTY_FUNCTION__
))
3465 "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", 3465, __extension__ __PRETTY_FUNCTION__
))
;
3466 OMPAssumeGlobal.push_back(AA);
3467
3468 // The OMPAssumeGlobal scope above will take care of new declarations but
3469 // we also want to apply the assumption to existing ones, e.g., to
3470 // declarations in included headers. To this end, we traverse all existing
3471 // declaration contexts and annotate function declarations here.
3472 SmallVector<DeclContext *, 8> DeclContexts;
3473 auto *Ctx = CurContext;
3474 while (Ctx->getLexicalParent())
3475 Ctx = Ctx->getLexicalParent();
3476 DeclContexts.push_back(Ctx);
3477 while (!DeclContexts.empty()) {
3478 DeclContext *DC = DeclContexts.pop_back_val();
3479 for (auto *SubDC : DC->decls()) {
3480 if (SubDC->isInvalidDecl())
3481 continue;
3482 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3483 DeclContexts.push_back(CTD->getTemplatedDecl());
3484 llvm::append_range(DeclContexts, CTD->specializations());
3485 continue;
3486 }
3487 if (auto *DC = dyn_cast<DeclContext>(SubDC))
3488 DeclContexts.push_back(DC);
3489 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3490 F->addAttr(AA);
3491 continue;
3492 }
3493 }
3494 }
3495}
3496
3497void Sema::ActOnOpenMPEndAssumesDirective() {
3498 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", 3498, __extension__ __PRETTY_FUNCTION__
))
;
3499 OMPAssumeScoped.pop_back();
3500}
3501
3502OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3503 ArrayRef<OMPClause *> ClauseList) {
3504 /// For target specific clauses, the requires directive cannot be
3505 /// specified after the handling of any of the target regions in the
3506 /// current compilation unit.
3507 ArrayRef<SourceLocation> TargetLocations =
3508 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3509 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3510 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3511 for (const OMPClause *CNew : ClauseList) {
3512 // Check if any of the requires clauses affect target regions.
3513 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3514 isa<OMPUnifiedAddressClause>(CNew) ||
3515 isa<OMPReverseOffloadClause>(CNew) ||
3516 isa<OMPDynamicAllocatorsClause>(CNew)) {
3517 Diag(Loc, diag::err_omp_directive_before_requires)
3518 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3519 for (SourceLocation TargetLoc : TargetLocations) {
3520 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3521 << "target";
3522 }
3523 } else if (!AtomicLoc.isInvalid() &&
3524 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3525 Diag(Loc, diag::err_omp_directive_before_requires)
3526 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3527 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3528 << "atomic";
3529 }
3530 }
3531 }
3532
3533 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3534 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3535 ClauseList);
3536 return nullptr;
3537}
3538
3539static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3540 const ValueDecl *D,
3541 const DSAStackTy::DSAVarData &DVar,
3542 bool IsLoopIterVar) {
3543 if (DVar.RefExpr) {
3544 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3545 << getOpenMPClauseName(DVar.CKind);
3546 return;
3547 }
3548 enum {
3549 PDSA_StaticMemberShared,
3550 PDSA_StaticLocalVarShared,
3551 PDSA_LoopIterVarPrivate,
3552 PDSA_LoopIterVarLinear,
3553 PDSA_LoopIterVarLastprivate,
3554 PDSA_ConstVarShared,
3555 PDSA_GlobalVarShared,
3556 PDSA_TaskVarFirstprivate,
3557 PDSA_LocalVarPrivate,
3558 PDSA_Implicit
3559 } Reason = PDSA_Implicit;
3560 bool ReportHint = false;
3561 auto ReportLoc = D->getLocation();
3562 auto *VD = dyn_cast<VarDecl>(D);
3563 if (IsLoopIterVar) {
3564 if (DVar.CKind == OMPC_private)
3565 Reason = PDSA_LoopIterVarPrivate;
3566 else if (DVar.CKind == OMPC_lastprivate)
3567 Reason = PDSA_LoopIterVarLastprivate;
3568 else
3569 Reason = PDSA_LoopIterVarLinear;
3570 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3571 DVar.CKind == OMPC_firstprivate) {
3572 Reason = PDSA_TaskVarFirstprivate;
3573 ReportLoc = DVar.ImplicitDSALoc;
3574 } else if (VD && VD->isStaticLocal())
3575 Reason = PDSA_StaticLocalVarShared;
3576 else if (VD && VD->isStaticDataMember())
3577 Reason = PDSA_StaticMemberShared;
3578 else if (VD && VD->isFileVarDecl())
3579 Reason = PDSA_GlobalVarShared;
3580 else if (D->getType().isConstant(SemaRef.getASTContext()))
3581 Reason = PDSA_ConstVarShared;
3582 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3583 ReportHint = true;
3584 Reason = PDSA_LocalVarPrivate;
3585 }
3586 if (Reason != PDSA_Implicit) {
3587 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3588 << Reason << ReportHint
3589 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3590 } else if (DVar.ImplicitDSALoc.isValid()) {
3591 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3592 << getOpenMPClauseName(DVar.CKind);
3593 }
3594}
3595
3596static OpenMPMapClauseKind
3597getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3598 bool IsAggregateOrDeclareTarget) {
3599 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3600 switch (M) {
3601 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3602 Kind = OMPC_MAP_alloc;
3603 break;
3604 case OMPC_DEFAULTMAP_MODIFIER_to:
3605 Kind = OMPC_MAP_to;
3606 break;
3607 case OMPC_DEFAULTMAP_MODIFIER_from:
3608 Kind = OMPC_MAP_from;
3609 break;
3610 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3611 Kind = OMPC_MAP_tofrom;
3612 break;
3613 case OMPC_DEFAULTMAP_MODIFIER_present:
3614 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3615 // If implicit-behavior is present, each variable referenced in the
3616 // construct in the category specified by variable-category is treated as if
3617 // it had been listed in a map clause with the map-type of alloc and
3618 // map-type-modifier of present.
3619 Kind = OMPC_MAP_alloc;
3620 break;
3621 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3622 case OMPC_DEFAULTMAP_MODIFIER_last:
3623 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "clang/lib/Sema/SemaOpenMP.cpp", 3623)
;
3624 case OMPC_DEFAULTMAP_MODIFIER_none:
3625 case OMPC_DEFAULTMAP_MODIFIER_default:
3626 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3627 // IsAggregateOrDeclareTarget could be true if:
3628 // 1. the implicit behavior for aggregate is tofrom
3629 // 2. it's a declare target link
3630 if (IsAggregateOrDeclareTarget) {
3631 Kind = OMPC_MAP_tofrom;
3632 break;
3633 }
3634 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "clang/lib/Sema/SemaOpenMP.cpp", 3634)
;
3635 }
3636 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", 3636, __extension__ __PRETTY_FUNCTION__
))
;
3637 return Kind;
3638}
3639
3640namespace {
3641class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3642 DSAStackTy *Stack;
3643 Sema &SemaRef;
3644 bool ErrorFound = false;
3645 bool TryCaptureCXXThisMembers = false;
3646 CapturedStmt *CS = nullptr;
3647 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3648 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3649 llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3650 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3651 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3652 ImplicitMapModifier[DefaultmapKindNum];
3653 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3654 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3655
3656 void VisitSubCaptures(OMPExecutableDirective *S) {
3657 // Check implicitly captured variables.
3658 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3659 return;
3660 if (S->getDirectiveKind() == OMPD_atomic ||
3661 S->getDirectiveKind() == OMPD_critical ||
3662 S->getDirectiveKind() == OMPD_section ||
3663 S->getDirectiveKind() == OMPD_master ||
3664 S->getDirectiveKind() == OMPD_masked ||
3665 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3666 Visit(S->getAssociatedStmt());
3667 return;
3668 }
3669 visitSubCaptures(S->getInnermostCapturedStmt());
3670 // Try to capture inner this->member references to generate correct mappings
3671 // and diagnostics.
3672 if (TryCaptureCXXThisMembers ||
3673 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3674 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3675 [](const CapturedStmt::Capture &C) {
3676 return C.capturesThis();
3677 }))) {
3678 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3679 TryCaptureCXXThisMembers = true;
3680 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3681 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3682 }
3683 // In tasks firstprivates are not captured anymore, need to analyze them
3684 // explicitly.
3685 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3686 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3687 for (OMPClause *C : S->clauses())
3688 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3689 for (Expr *Ref : FC->varlists())
3690 Visit(Ref);
3691 }
3692 }
3693 }
3694
3695public:
3696 void VisitDeclRefExpr(DeclRefExpr *E) {
3697 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3698 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3699 E->isInstantiationDependent())
3700 return;
3701 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3702 // Check the datasharing rules for the expressions in the clauses.
3703 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3704 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3705 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3706 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3707 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3708 Visit(CED->getInit());
3709 return;
3710 }
3711 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3712 // Do not analyze internal variables and do not enclose them into
3713 // implicit clauses.
3714 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3715 return;
3716 VD = VD->getCanonicalDecl();
3717 // Skip internally declared variables.
3718 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3719 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3720 !Stack->isImplicitTaskFirstprivate(VD))
3721 return;
3722 // Skip allocators in uses_allocators clauses.
3723 if (Stack->isUsesAllocatorsDecl(VD))
3724 return;
3725
3726 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3727 // Check if the variable has explicit DSA set and stop analysis if it so.
3728 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3729 return;
3730
3731 // Skip internally declared static variables.
3732 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3733 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3734 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3735 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3736 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3737 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3738 !Stack->isImplicitTaskFirstprivate(VD))
3739 return;
3740
3741 SourceLocation ELoc = E->getExprLoc();
3742 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3743 // The default(none) clause requires that each variable that is referenced
3744 // in the construct, and does not have a predetermined data-sharing
3745 // attribute, must have its data-sharing attribute explicitly determined
3746 // by being listed in a data-sharing attribute clause.
3747 if (DVar.CKind == OMPC_unknown &&
3748 (Stack->getDefaultDSA() == DSA_none ||
3749 Stack->getDefaultDSA() == DSA_private ||
3750 Stack->getDefaultDSA() == DSA_firstprivate) &&
3751 isImplicitOrExplicitTaskingRegion(DKind) &&
3752 VarsWithInheritedDSA.count(VD) == 0) {
3753 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3754 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3755 Stack->getDefaultDSA() == DSA_private)) {
3756 DSAStackTy::DSAVarData DVar =
3757 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3758 InheritedDSA = DVar.CKind == OMPC_unknown;
3759 }
3760 if (InheritedDSA)
3761 VarsWithInheritedDSA[VD] = E;
3762 if (Stack->getDefaultDSA() == DSA_none)
3763 return;
3764 }
3765
3766 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3767 // If implicit-behavior is none, each variable referenced in the
3768 // construct that does not have a predetermined data-sharing attribute
3769 // and does not appear in a to or link clause on a declare target
3770 // directive must be listed in a data-mapping attribute clause, a
3771 // data-sharing attribute clause (including a data-sharing attribute
3772 // clause on a combined construct where target. is one of the
3773 // constituent constructs), or an is_device_ptr clause.
3774 OpenMPDefaultmapClauseKind ClauseKind =
3775 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3776 if (SemaRef.getLangOpts().OpenMP >= 50) {
3777 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3778 OMPC_DEFAULTMAP_MODIFIER_none;
3779 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3780 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3781 // Only check for data-mapping attribute and is_device_ptr here
3782 // since we have already make sure that the declaration does not
3783 // have a data-sharing attribute above
3784 if (!Stack->checkMappableExprComponentListsForDecl(
3785 VD, /*CurrentRegionOnly=*/true,
3786 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3787 MapExprComponents,
3788 OpenMPClauseKind) {
3789 auto MI = MapExprComponents.rbegin();
3790 auto ME = MapExprComponents.rend();
3791 return MI != ME && MI->getAssociatedDeclaration() == VD;
3792 })) {
3793 VarsWithInheritedDSA[VD] = E;
3794 return;
3795 }
3796 }
3797 }
3798 if (SemaRef.getLangOpts().OpenMP > 50) {
3799 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3800 OMPC_DEFAULTMAP_MODIFIER_present;
3801 if (IsModifierPresent) {
3802 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3803 OMPC_MAP_MODIFIER_present)) {
3804 ImplicitMapModifier[ClauseKind].push_back(
3805 OMPC_MAP_MODIFIER_present);
3806 }
3807 }
3808 }
3809
3810 if (isOpenMPTargetExecutionDirective(DKind) &&
3811 !Stack->isLoopControlVariable(VD).first) {
3812 if (!Stack->checkMappableExprComponentListsForDecl(
3813 VD, /*CurrentRegionOnly=*/true,
3814 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3815 StackComponents,
3816 OpenMPClauseKind) {
3817 if (SemaRef.LangOpts.OpenMP >= 50)
3818 return !StackComponents.empty();
3819 // Variable is used if it has been marked as an array, array
3820 // section, array shaping or the variable iself.
3821 return StackComponents.size() == 1 ||
3822 llvm::all_of(
3823 llvm::drop_begin(llvm::reverse(StackComponents)),
3824 [](const OMPClauseMappableExprCommon::
3825 MappableComponent &MC) {
3826 return MC.getAssociatedDeclaration() ==
3827 nullptr &&
3828 (isa<OMPArraySectionExpr>(
3829 MC.getAssociatedExpression()) ||
3830 isa<OMPArrayShapingExpr>(
3831 MC.getAssociatedExpression()) ||
3832 isa<ArraySubscriptExpr>(
3833 MC.getAssociatedExpression()));
3834 });
3835 })) {
3836 bool IsFirstprivate = false;
3837 // By default lambdas are captured as firstprivates.
3838 if (const auto *RD =
3839 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3840 IsFirstprivate = RD->isLambda();
3841 IsFirstprivate =
3842 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3843 if (IsFirstprivate) {
3844 ImplicitFirstprivate.emplace_back(E);
3845 } else {
3846 OpenMPDefaultmapClauseModifier M =
3847 Stack->getDefaultmapModifier(ClauseKind);
3848 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3849 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3850 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3851 }
3852 return;
3853 }
3854 }
3855
3856 // OpenMP [2.9.3.6, Restrictions, p.2]
3857 // A list item that appears in a reduction clause of the innermost
3858 // enclosing worksharing or parallel construct may not be accessed in an
3859 // explicit task.
3860 DVar = Stack->hasInnermostDSA(
3861 VD,
3862 [](OpenMPClauseKind C, bool AppliedToPointee) {
3863 return C == OMPC_reduction && !AppliedToPointee;
3864 },
3865 [](OpenMPDirectiveKind K) {
3866 return isOpenMPParallelDirective(K) ||
3867 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3868 },
3869 /*FromParent=*/true);
3870 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3871 ErrorFound = true;
3872 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3873 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3874 return;
3875 }
3876
3877 // Define implicit data-sharing attributes for task.
3878 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3879 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3880 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3881 DVar.CKind == OMPC_firstprivate) ||
3882 (Stack->getDefaultDSA() == DSA_private &&
3883 DVar.CKind == OMPC_private)) &&
3884 !DVar.RefExpr)) &&
3885 !Stack->isLoopControlVariable(VD).first) {
3886 if (Stack->getDefaultDSA() == DSA_private)
3887 ImplicitPrivate.push_back(E);
3888 else
3889 ImplicitFirstprivate.push_back(E);
3890 return;
3891 }
3892
3893 // Store implicitly used globals with declare target link for parent
3894 // target.
3895 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3896 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3897 Stack->addToParentTargetRegionLinkGlobals(E);
3898 return;
3899 }
3900 }
3901 }
3902 void VisitMemberExpr(MemberExpr *E) {
3903 if (E->isTypeDependent() || E->isValueDependent() ||
3904 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3905 return;
3906 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3907 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3908 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3909 if (!FD)
3910 return;
3911 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3912 // Check if the variable has explicit DSA set and stop analysis if it
3913 // so.
3914 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3915 return;
3916
3917 if (isOpenMPTargetExecutionDirective(DKind) &&
3918 !Stack->isLoopControlVariable(FD).first &&
3919 !Stack->checkMappableExprComponentListsForDecl(
3920 FD, /*CurrentRegionOnly=*/true,
3921 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3922 StackComponents,
3923 OpenMPClauseKind) {
3924 return isa<CXXThisExpr>(
3925 cast<MemberExpr>(
3926 StackComponents.back().getAssociatedExpression())
3927 ->getBase()
3928 ->IgnoreParens());
3929 })) {
3930 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3931 // A bit-field cannot appear in a map clause.
3932 //
3933 if (FD->isBitField())
3934 return;
3935
3936 // Check to see if the member expression is referencing a class that
3937 // has already been explicitly mapped
3938 if (Stack->isClassPreviouslyMapped(TE->getType()))
3939 return;
3940
3941 OpenMPDefaultmapClauseModifier Modifier =
3942 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3943 OpenMPDefaultmapClauseKind ClauseKind =
3944 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3945 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3946 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3947 ImplicitMap[ClauseKind][Kind].emplace_back(E);
3948 return;
3949 }
3950
3951 SourceLocation ELoc = E->getExprLoc();
3952 // OpenMP [2.9.3.6, Restrictions, p.2]
3953 // A list item that appears in a reduction clause of the innermost
3954 // enclosing worksharing or parallel construct may not be accessed in
3955 // an explicit task.
3956 DVar = Stack->hasInnermostDSA(
3957 FD,
3958 [](OpenMPClauseKind C, bool AppliedToPointee) {
3959 return C == OMPC_reduction && !AppliedToPointee;
3960 },
3961 [](OpenMPDirectiveKind K) {
3962 return isOpenMPParallelDirective(K) ||
3963 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3964 },
3965 /*FromParent=*/true);
3966 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3967 ErrorFound = true;
3968 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3969 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3970 return;
3971 }
3972
3973 // Define implicit data-sharing attributes for task.
3974 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3975 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3976 !Stack->isLoopControlVariable(FD).first) {
3977 // Check if there is a captured expression for the current field in the
3978 // region. Do not mark it as firstprivate unless there is no captured
3979 // expression.
3980 // TODO: try to make it firstprivate.
3981 if (DVar.CKind != OMPC_unknown)
3982 ImplicitFirstprivate.push_back(E);
3983 }
3984 return;
3985 }
3986 if (isOpenMPTargetExecutionDirective(DKind)) {
3987 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3988 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3989 Stack->getCurrentDirective(),
3990 /*NoDiagnose=*/true))
3991 return;
3992 const auto *VD = cast<ValueDecl>(
3993 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3994 if (!Stack->checkMappableExprComponentListsForDecl(
3995 VD, /*CurrentRegionOnly=*/true,
3996 [&CurComponents](
3997 OMPClauseMappableExprCommon::MappableExprComponentListRef
3998 StackComponents,
3999 OpenMPClauseKind) {
4000 auto CCI = CurComponents.rbegin();
4001 auto CCE = CurComponents.rend();
4002 for (const auto &SC : llvm::reverse(StackComponents)) {
4003 // Do both expressions have the same kind?
4004 if (CCI->getAssociatedExpression()->getStmtClass() !=
4005 SC.getAssociatedExpression()->getStmtClass())
4006 if (!((isa<OMPArraySectionExpr>(
4007 SC.getAssociatedExpression()) ||
4008 isa<OMPArrayShapingExpr>(
4009 SC.getAssociatedExpression())) &&
4010 isa<ArraySubscriptExpr>(
4011 CCI->getAssociatedExpression())))
4012 return false;
4013
4014 const Decl *CCD = CCI->getAssociatedDeclaration();
4015 const Decl *SCD = SC.getAssociatedDeclaration();
4016 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4017 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4018 if (SCD != CCD)
4019 return false;
4020 std::advance(CCI, 1);
4021 if (CCI == CCE)
4022 break;
4023 }
4024 return true;
4025 })) {
4026 Visit(E->getBase());
4027 }
4028 } else if (!TryCaptureCXXThisMembers) {
4029 Visit(E->getBase());
4030 }
4031 }
4032 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4033 for (OMPClause *C : S->clauses()) {
4034 // Skip analysis of arguments of private clauses for task|target
4035 // directives.
4036 if (isa_and_nonnull<OMPPrivateClause>(C))
4037 continue;
4038 // Skip analysis of arguments of implicitly defined firstprivate clause
4039 // for task|target directives.
4040 // Skip analysis of arguments of implicitly defined map clause for target
4041 // directives.
4042 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4043 C->isImplicit() &&
4044 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4045 for (Stmt *CC : C->children()) {
4046 if (CC)
4047 Visit(CC);
4048 }
4049 }
4050 }
4051 // Check implicitly captured variables.
4052 VisitSubCaptures(S);
4053 }
4054
4055 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4056 // Loop transformation directives do not introduce data sharing
4057 VisitStmt(S);
4058 }
4059
4060 void VisitCallExpr(CallExpr *S) {
4061 for (Stmt *C : S->arguments()) {
4062 if (C) {
4063 // Check implicitly captured variables in the task-based directives to
4064 // check if they must be firstprivatized.
4065 Visit(C);
4066 }
4067 }
4068 if (Expr *Callee = S->getCallee())
4069 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
4070 Visit(CE->getBase());
4071 }
4072 void VisitStmt(Stmt *S) {
4073 for (Stmt *C : S->children()) {
4074 if (C) {
4075 // Check implicitly captured variables in the task-based directives to
4076 // check if they must be firstprivatized.
4077 Visit(C);
4078 }
4079 }
4080 }
4081
4082 void visitSubCaptures(CapturedStmt *S) {
4083 for (const CapturedStmt::Capture &Cap : S->captures()) {
4084 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4085 continue;
4086 VarDecl *VD = Cap.getCapturedVar();
4087 // Do not try to map the variable if it or its sub-component was mapped
4088 // already.
4089 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4090 Stack->checkMappableExprComponentListsForDecl(
4091 VD, /*CurrentRegionOnly=*/true,
4092 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4093 OpenMPClauseKind) { return true; }))
4094 continue;
4095 DeclRefExpr *DRE = buildDeclRefExpr(
4096 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4097 Cap.getLocation(), /*RefersToCapture=*/true);
4098 Visit(DRE);
4099 }
4100 }
4101 bool isErrorFound() const { return ErrorFound; }
4102 ArrayRef<Expr *> getImplicitFirstprivate() const {
4103 return ImplicitFirstprivate;
4104 }
4105 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4106 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4107 OpenMPMapClauseKind MK) const {
4108 return ImplicitMap[DK][MK];
4109 }
4110 ArrayRef<OpenMPMapModifierKind>
4111 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4112 return ImplicitMapModifier[Kind];
4113 }
4114 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4115 return VarsWithInheritedDSA;
4116 }
4117
4118 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4119 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4120 // Process declare target link variables for the target directives.
4121 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4122 for (DeclRefExpr *E : Stack->getLinkGlobals())
4123 Visit(E);
4124 }
4125 }
4126};
4127} // namespace
4128
4129static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4130 OpenMPDirectiveKind DKind,
4131 bool ScopeEntry) {
4132 SmallVector<llvm::omp::TraitProperty, 8> Traits;
4133 if (isOpenMPTargetExecutionDirective(DKind))
4134 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4135 if (isOpenMPTeamsDirective(DKind))
4136 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4137 if (isOpenMPParallelDirective(DKind))
4138 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4139 if (isOpenMPWorksharingDirective(DKind))
4140 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4141 if (isOpenMPSimdDirective(DKind))
4142 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4143 Stack->handleConstructTrait(Traits, ScopeEntry);
4144}
4145
4146void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4147 switch (DKind) {
4148 case OMPD_parallel:
4149 case OMPD_parallel_for:
4150 case OMPD_parallel_for_simd:
4151 case OMPD_parallel_sections:
4152 case OMPD_parallel_master:
4153 case OMPD_parallel_masked:
4154 case OMPD_parallel_loop:
4155 case OMPD_teams:
4156 case OMPD_teams_distribute:
4157 case OMPD_teams_distribute_simd: {
4158 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4159 QualType KmpInt32PtrTy =
4160 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4161 Sema::CapturedParamNameType Params[] = {
4162 std::make_pair(".global_tid.", KmpInt32PtrTy),
4163 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4164 std::make_pair(StringRef(), QualType()) // __context with shared vars
4165 };
4166 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4167 Params);
4168 break;
4169 }
4170 case OMPD_target_teams:
4171 case OMPD_target_parallel:
4172 case OMPD_target_parallel_for:
4173 case OMPD_target_parallel_for_simd:
4174 case OMPD_target_teams_loop:
4175 case OMPD_target_parallel_loop:
4176 case OMPD_target_teams_distribute:
4177 case OMPD_target_teams_distribute_simd: {
4178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4179 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4180 QualType KmpInt32PtrTy =
4181 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4182 QualType Args[] = {VoidPtrTy};
4183 FunctionProtoType::ExtProtoInfo EPI;
4184 EPI.Variadic = true;
4185 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4186 Sema::CapturedParamNameType Params[] = {
4187 std::make_pair(".global_tid.", KmpInt32Ty),
4188 std::make_pair(".part_id.", KmpInt32PtrTy),
4189 std::make_pair(".privates.", VoidPtrTy),
4190 std::make_pair(
4191 ".copy_fn.",
4192 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4193 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4194 std::make_pair(StringRef(), QualType()) // __context with shared vars
4195 };
4196 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4197 Params, /*OpenMPCaptureLevel=*/0);
4198 // Mark this captured region as inlined, because we don't use outlined
4199 // function directly.
4200 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4201 AlwaysInlineAttr::CreateImplicit(
4202 Context, {}, AttributeCommonInfo::AS_Keyword,
4203 AlwaysInlineAttr::Keyword_forceinline));
4204 Sema::CapturedParamNameType ParamsTarget[] = {
4205 std::make_pair(StringRef(), QualType()) // __context with shared vars
4206 };
4207 // Start a captured region for 'target' with no implicit parameters.
4208 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4209 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4210 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4211 std::make_pair(".global_tid.", KmpInt32PtrTy),
4212 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4213 std::make_pair(StringRef(), QualType()) // __context with shared vars
4214 };
4215 // Start a captured region for 'teams' or 'parallel'. Both regions have
4216 // the same implicit parameters.
4217 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4218 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4219 break;
4220 }
4221 case OMPD_target:
4222 case OMPD_target_simd: {
4223 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4224 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4225 QualType KmpInt32PtrTy =
4226 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4227 QualType Args[] = {VoidPtrTy};
4228 FunctionProtoType::ExtProtoInfo EPI;
4229 EPI.Variadic = true;
4230 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4231 Sema::CapturedParamNameType Params[] = {
4232 std::make_pair(".global_tid.", KmpInt32Ty),
4233 std::make_pair(".part_id.", KmpInt32PtrTy),
4234 std::make_pair(".privates.", VoidPtrTy),
4235 std::make_pair(
4236 ".copy_fn.",
4237 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4238 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4239 std::make_pair(StringRef(), QualType()) // __context with shared vars
4240 };
4241 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4242 Params, /*OpenMPCaptureLevel=*/0);
4243 // Mark this captured region as inlined, because we don't use outlined
4244 // function directly.
4245 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4246 AlwaysInlineAttr::CreateImplicit(
4247 Context, {}, AttributeCommonInfo::AS_Keyword,
4248 AlwaysInlineAttr::Keyword_forceinline));
4249 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4250 std::make_pair(StringRef(), QualType()),
4251 /*OpenMPCaptureLevel=*/1);
4252 break;
4253 }
4254 case OMPD_atomic:
4255 case OMPD_critical:
4256 case OMPD_section:
4257 case OMPD_master:
4258 case OMPD_masked:
4259 case OMPD_tile:
4260 case OMPD_unroll:
4261 break;
4262 case OMPD_loop:
4263 // TODO: 'loop' may require additional parameters depending on the binding.
4264 // Treat similar to OMPD_simd/OMPD_for for now.
4265 case OMPD_simd:
4266 case OMPD_for:
4267 case OMPD_for_simd:
4268 case OMPD_sections:
4269 case OMPD_single:
4270 case OMPD_taskgroup:
4271 case OMPD_distribute:
4272 case OMPD_distribute_simd:
4273 case OMPD_ordered:
4274 case OMPD_target_data:
4275 case OMPD_dispatch: {
4276 Sema::CapturedParamNameType Params[] = {
4277 std::make_pair(StringRef(), QualType()) // __context with shared vars
4278 };
4279 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4280 Params);
4281 break;
4282 }
4283 case OMPD_task: {
4284 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4285 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4286 QualType KmpInt32PtrTy =
4287 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4288 QualType Args[] = {VoidPtrTy};
4289 FunctionProtoType::ExtProtoInfo EPI;
4290 EPI.Variadic = true;
4291 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4292 Sema::CapturedParamNameType Params[] = {
4293 std::make_pair(".global_tid.", KmpInt32Ty),
4294 std::make_pair(".part_id.", KmpInt32PtrTy),
4295 std::make_pair(".privates.", VoidPtrTy),
4296 std::make_pair(
4297 ".copy_fn.",
4298 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4299 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4300 std::make_pair(StringRef(), QualType()) // __context with shared vars
4301 };
4302 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4303 Params);
4304 // Mark this captured region as inlined, because we don't use outlined
4305 // function directly.
4306 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4307 AlwaysInlineAttr::CreateImplicit(
4308 Context, {}, AttributeCommonInfo::AS_Keyword,
4309 AlwaysInlineAttr::Keyword_forceinline));
4310 break;
4311 }
4312 case OMPD_taskloop:
4313 case OMPD_taskloop_simd:
4314 case OMPD_master_taskloop:
4315 case OMPD_masked_taskloop:
4316 case OMPD_masked_taskloop_simd:
4317 case OMPD_master_taskloop_simd: {
4318 QualType KmpInt32Ty =
4319 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4320 .withConst();
4321 QualType KmpUInt64Ty =
4322 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4323 .withConst();
4324 QualType KmpInt64Ty =
4325 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4326 .withConst();
4327 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4328 QualType KmpInt32PtrTy =
4329 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4330 QualType Args[] = {VoidPtrTy};
4331 FunctionProtoType::ExtProtoInfo EPI;
4332 EPI.Variadic = true;
4333 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4334 Sema::CapturedParamNameType Params[] = {
4335 std::make_pair(".global_tid.", KmpInt32Ty),
4336 std::make_pair(".part_id.", KmpInt32PtrTy),
4337 std::make_pair(".privates.", VoidPtrTy),
4338 std::make_pair(
4339 ".copy_fn.",
4340 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4341 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4342 std::make_pair(".lb.", KmpUInt64Ty),
4343 std::make_pair(".ub.", KmpUInt64Ty),
4344 std::make_pair(".st.", KmpInt64Ty),
4345 std::make_pair(".liter.", KmpInt32Ty),
4346 std::make_pair(".reductions.", VoidPtrTy),
4347 std::make_pair(StringRef(), QualType()) // __context with shared vars
4348 };
4349 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4350 Params);
4351 // Mark this captured region as inlined, because we don't use outlined
4352 // function directly.
4353 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4354 AlwaysInlineAttr::CreateImplicit(
4355 Context, {}, AttributeCommonInfo::AS_Keyword,
4356 AlwaysInlineAttr::Keyword_forceinline));
4357 break;
4358 }
4359 case OMPD_parallel_masked_taskloop:
4360 case OMPD_parallel_masked_taskloop_simd:
4361 case OMPD_parallel_master_taskloop:
4362 case OMPD_parallel_master_taskloop_simd: {
4363 QualType KmpInt32Ty =
4364 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4365 .withConst();
4366 QualType KmpUInt64Ty =
4367 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4368 .withConst();
4369 QualType KmpInt64Ty =
4370 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4371 .withConst();
4372 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4373 QualType KmpInt32PtrTy =
4374 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4375 Sema::CapturedParamNameType ParamsParallel[] = {
4376 std::make_pair(".global_tid.", KmpInt32PtrTy),
4377 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4378 std::make_pair(StringRef(), QualType()) // __context with shared vars
4379 };
4380 // Start a captured region for 'parallel'.
4381 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4382 ParamsParallel, /*OpenMPCaptureLevel=*/0);
4383 QualType Args[] = {VoidPtrTy};
4384 FunctionProtoType::ExtProtoInfo EPI;
4385 EPI.Variadic = true;
4386 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4387 Sema::CapturedParamNameType Params[] = {
4388 std::make_pair(".global_tid.", KmpInt32Ty),
4389 std::make_pair(".part_id.", KmpInt32PtrTy),
4390 std::make_pair(".privates.", VoidPtrTy),
4391 std::make_pair(
4392 ".copy_fn.",
4393 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4394 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4395 std::make_pair(".lb.", KmpUInt64Ty),
4396 std::make_pair(".ub.", KmpUInt64Ty),
4397 std::make_pair(".st.", KmpInt64Ty),
4398 std::make_pair(".liter.", KmpInt32Ty),
4399 std::make_pair(".reductions.", VoidPtrTy),
4400 std::make_pair(StringRef(), QualType()) // __context with shared vars
4401 };
4402 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4403 Params, /*OpenMPCaptureLevel=*/1);
4404 // Mark this captured region as inlined, because we don't use outlined
4405 // function directly.
4406 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4407 AlwaysInlineAttr::CreateImplicit(
4408 Context, {}, AttributeCommonInfo::AS_Keyword,
4409 AlwaysInlineAttr::Keyword_forceinline));
4410 break;
4411 }
4412 case OMPD_distribute_parallel_for_simd:
4413 case OMPD_distribute_parallel_for: {
4414 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4415 QualType KmpInt32PtrTy =
4416 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4417 Sema::CapturedParamNameType Params[] = {
4418 std::make_pair(".global_tid.", KmpInt32PtrTy),
4419 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4420 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4421 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4422 std::make_pair(StringRef(), QualType()) // __context with shared vars
4423 };
4424 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4425 Params);
4426 break;
4427 }
4428 case OMPD_target_teams_distribute_parallel_for:
4429 case OMPD_target_teams_distribute_parallel_for_simd: {
4430 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4431 QualType KmpInt32PtrTy =
4432 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4433 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4434
4435 QualType Args[] = {VoidPtrTy};
4436 FunctionProtoType::ExtProtoInfo EPI;
4437 EPI.Variadic = true;
4438 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4439 Sema::CapturedParamNameType Params[] = {
4440 std::make_pair(".global_tid.", KmpInt32Ty),
4441 std::make_pair(".part_id.", KmpInt32PtrTy),
4442 std::make_pair(".privates.", VoidPtrTy),
4443 std::make_pair(
4444 ".copy_fn.",
4445 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4446 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4447 std::make_pair(StringRef(), QualType()) // __context with shared vars
4448 };
4449 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4450 Params, /*OpenMPCaptureLevel=*/0);
4451 // Mark this captured region as inlined, because we don't use outlined
4452 // function directly.
4453 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4454 AlwaysInlineAttr::CreateImplicit(
4455 Context, {}, AttributeCommonInfo::AS_Keyword,
4456 AlwaysInlineAttr::Keyword_forceinline));
4457 Sema::CapturedParamNameType ParamsTarget[] = {
4458 std::make_pair(StringRef(), QualType()) // __context with shared vars
4459 };
4460 // Start a captured region for 'target' with no implicit parameters.
4461 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4462 ParamsTarget, /*OpenMPCaptureLevel=*/1);
4463
4464 Sema::CapturedParamNameType ParamsTeams[] = {
4465 std::make_pair(".global_tid.", KmpInt32PtrTy),
4466 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4467 std::make_pair(StringRef(), QualType()) // __context with shared vars
4468 };
4469 // Start a captured region for 'target' with no implicit parameters.
4470 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4471 ParamsTeams, /*OpenMPCaptureLevel=*/2);
4472
4473 Sema::CapturedParamNameType ParamsParallel[] = {
4474 std::make_pair(".global_tid.", KmpInt32PtrTy),
4475 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4476 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4477 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4478 std::make_pair(StringRef(), QualType()) // __context with shared vars
4479 };
4480 // Start a captured region for 'teams' or 'parallel'. Both regions have
4481 // the same implicit parameters.
4482 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4483 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4484 break;
4485 }
4486
4487 case OMPD_teams_loop: {
4488 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4489 QualType KmpInt32PtrTy =
4490 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4491
4492 Sema::CapturedParamNameType ParamsTeams[] = {
4493 std::make_pair(".global_tid.", KmpInt32PtrTy),
4494 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4495 std::make_pair(StringRef(), QualType()) // __context with shared vars
4496 };
4497 // Start a captured region for 'teams'.
4498 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4499 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4500 break;
4501 }
4502
4503 case OMPD_teams_distribute_parallel_for:
4504 case OMPD_teams_distribute_parallel_for_simd: {
4505 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4506 QualType KmpInt32PtrTy =
4507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4508
4509 Sema::CapturedParamNameType ParamsTeams[] = {
4510 std::make_pair(".global_tid.", KmpInt32PtrTy),
4511 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4512 std::make_pair(StringRef(), QualType()) // __context with shared vars
4513 };
4514 // Start a captured region for 'target' with no implicit parameters.
4515 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4516 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4517
4518 Sema::CapturedParamNameType ParamsParallel[] = {
4519 std::make_pair(".global_tid.", KmpInt32PtrTy),
4520 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4521 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4522 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4523 std::make_pair(StringRef(), QualType()) // __context with shared vars
4524 };
4525 // Start a captured region for 'teams' or 'parallel'. Both regions have
4526 // the same implicit parameters.
4527 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4528 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4529 break;
4530 }
4531 case OMPD_target_update:
4532 case OMPD_target_enter_data:
4533 case OMPD_target_exit_data: {
4534 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4535 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4536 QualType KmpInt32PtrTy =
4537 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4538 QualType Args[] = {VoidPtrTy};
4539 FunctionProtoType::ExtProtoInfo EPI;
4540 EPI.Variadic = true;
4541 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4542 Sema::CapturedParamNameType Params[] = {
4543 std::make_pair(".global_tid.", KmpInt32Ty),
4544 std::make_pair(".part_id.", KmpInt32PtrTy),
4545 std::make_pair(".privates.", VoidPtrTy),
4546 std::make_pair(
4547 ".copy_fn.",
4548 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4549 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4550 std::make_pair(StringRef(), QualType()) // __context with shared vars
4551 };
4552 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4553 Params);
4554 // Mark this captured region as inlined, because we don't use outlined
4555 // function directly.
4556 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4557 AlwaysInlineAttr::CreateImplicit(
4558 Context, {}, AttributeCommonInfo::AS_Keyword,
4559 AlwaysInlineAttr::Keyword_forceinline));
4560 break;
4561 }
4562 case OMPD_threadprivate:
4563 case OMPD_allocate:
4564 case OMPD_taskyield:
4565 case OMPD_error:
4566 case OMPD_barrier:
4567 case OMPD_taskwait:
4568 case OMPD_cancellation_point:
4569 case OMPD_cancel:
4570 case OMPD_flush:
4571 case OMPD_depobj:
4572 case OMPD_scan:
4573 case OMPD_declare_reduction:
4574 case OMPD_declare_mapper:
4575 case OMPD_declare_simd:
4576 case OMPD_declare_target:
4577 case OMPD_end_declare_target:
4578 case OMPD_requires:
4579 case OMPD_declare_variant:
4580 case OMPD_begin_declare_variant:
4581 case OMPD_end_declare_variant:
4582 case OMPD_metadirective:
4583 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "clang/lib/Sema/SemaOpenMP.cpp", 4583)
;
4584 case OMPD_unknown:
4585 default:
4586 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 4586)
;
4587 }
4588 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setContext(CurContext);
4589 handleDeclareVariantConstructTrait(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, DKind, /* ScopeEntry */ true);
4590}
4591
4592int Sema::getNumberOfConstructScopes(unsigned Level) const {
4593 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4594}
4595
4596int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4597 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4598 getOpenMPCaptureRegions(CaptureRegions, DKind);
4599 return CaptureRegions.size();
4600}
4601
4602static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4603 Expr *CaptureExpr, bool WithInit,
4604 DeclContext *CurContext,
4605 bool AsExpression) {
4606 assert(CaptureExpr)(static_cast <bool> (CaptureExpr) ? void (0) : __assert_fail
("CaptureExpr", "clang/lib/Sema/SemaOpenMP.cpp", 4606, __extension__
__PRETTY_FUNCTION__))
;
4607 ASTContext &C = S.getASTContext();
4608 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4609 QualType Ty = Init->getType();
4610 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4611 if (S.getLangOpts().CPlusPlus) {
4612 Ty = C.getLValueReferenceType(Ty);
4613 } else {
4614 Ty = C.getPointerType(Ty);
4615 ExprResult Res =
4616 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4617 if (!Res.isUsable())
4618 return nullptr;
4619 Init = Res.get();
4620 }
4621 WithInit = true;
4622 }
4623 auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4624 CaptureExpr->getBeginLoc());
4625 if (!WithInit)
4626 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4627 CurContext->addHiddenDecl(CED);
4628 Sema::TentativeAnalysisScope Trap(S);
4629 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4630 return CED;
4631}
4632
4633static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4634 bool WithInit) {
4635 OMPCapturedExprDecl *CD;
4636 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4637 CD = cast<OMPCapturedExprDecl>(VD);
4638 else
4639 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4640 S.CurContext,
4641 /*AsExpression=*/false);
4642 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4643 CaptureExpr->getExprLoc());
4644}
4645
4646static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4647 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4648 if (!Ref) {
4649 OMPCapturedExprDecl *CD = buildCaptureDecl(
4650 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4651 /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4652 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4653 CaptureExpr->getExprLoc());
4654 }
4655 ExprResult Res = Ref;
4656 if (!S.getLangOpts().CPlusPlus &&
4657 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4658 Ref->getType()->isPointerType()) {
4659 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4660 if (!Res.isUsable())
4661 return ExprError();
4662 }
4663 return S.DefaultLvalueConversion(Res.get());
4664}
4665
4666namespace {
4667// OpenMP directives parsed in this section are represented as a
4668// CapturedStatement with an associated statement. If a syntax error
4669// is detected during the parsing of the associated statement, the
4670// compiler must abort processing and close the CapturedStatement.
4671//
4672// Combined directives such as 'target parallel' have more than one
4673// nested CapturedStatements. This RAII ensures that we unwind out
4674// of all the nested CapturedStatements when an error is found.
4675class CaptureRegionUnwinderRAII {
4676private:
4677 Sema &S;
4678 bool &ErrorFound;
4679 OpenMPDirectiveKind DKind = OMPD_unknown;
4680
4681public:
4682 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4683 OpenMPDirectiveKind DKind)
4684 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4685 ~CaptureRegionUnwinderRAII() {
4686 if (ErrorFound) {
4687 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4688 while (--ThisCaptureLevel >= 0)
4689 S.ActOnCapturedRegionError();
4690 }
4691 }
4692};
4693} // namespace
4694
4695void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4696 // Capture variables captured by reference in lambdas for target-based
4697 // directives.
4698 if (!CurContext->isDependentContext() &&
4699 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4700 isOpenMPTargetDataManagementDirective(
4701 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4702 QualType Type = V->getType();
4703 if (const auto *RD = Type.getCanonicalType()
4704 .getNonReferenceType()
4705 ->getAsCXXRecordDecl()) {
4706 bool SavedForceCaptureByReferenceInTargetExecutable =
4707 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4708 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4709 /*V=*/true);
4710 if (RD->isLambda()) {
4711 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4712 FieldDecl *ThisCapture;
4713 RD->getCaptureFields(Captures, ThisCapture);
4714 for (const LambdaCapture &LC : RD->captures()) {
4715 if (LC.getCaptureKind() == LCK_ByRef) {
4716 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4717 DeclContext *VDC = VD->getDeclContext();
4718 if (!VDC->Encloses(CurContext))
4719 continue;
4720 MarkVariableReferenced(LC.getLocation(), VD);
4721 } else if (LC.getCaptureKind() == LCK_This) {
4722 QualType ThisTy = getCurrentThisType();
4723 if (!ThisTy.isNull() &&
4724 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4725 CheckCXXThisCapture(LC.getLocation());
4726 }
4727 }
4728 }
4729 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4730 SavedForceCaptureByReferenceInTargetExecutable);
4731 }
4732 }
4733}
4734
4735static bool checkOrderedOrderSpecified(Sema &S,
4736 const ArrayRef<OMPClause *> Clauses) {
4737 const OMPOrderedClause *Ordered = nullptr;
4738 const OMPOrderClause *Order = nullptr;
4739
4740 for (const OMPClause *Clause : Clauses) {
4741 if (Clause->getClauseKind() == OMPC_ordered)
4742 Ordered = cast<OMPOrderedClause>(Clause);
4743 else if (Clause->getClauseKind() == OMPC_order) {
4744 Order = cast<OMPOrderClause>(Clause);
4745 if (Order->getKind() != OMPC_ORDER_concurrent)
4746 Order = nullptr;
4747 }
4748 if (Ordered && Order)
4749 break;
4750 }
4751
4752 if (Ordered && Order) {
4753 S.Diag(Order->getKindKwLoc(),
4754 diag::err_omp_simple_clause_incompatible_with_ordered)
4755 << getOpenMPClauseName(OMPC_order)
4756 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4757 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4758 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4759 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4760 return true;
4761 }
4762 return false;
4763}
4764
4765StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4766 ArrayRef<OMPClause *> Clauses) {
4767 handleDeclareVariantConstructTrait(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(),
4768 /* ScopeEntry */ false);
4769 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_atomic ||
4770 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_critical ||
4771 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_section ||
4772 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_master ||
4773 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_masked)
4774 return S;
4775
4776 bool ErrorFound = false;
4777 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4778 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4779 if (!S.isUsable()) {
4780 ErrorFound = true;
4781 return StmtError();
4782 }
4783
4784 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4785 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4786 OMPOrderedClause *OC = nullptr;
4787 OMPScheduleClause *SC = nullptr;
4788 SmallVector<const OMPLinearClause *, 4> LCs;
4789 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4790 // This is required for proper codegen.
4791 for (OMPClause *Clause : Clauses) {
4792 if (!LangOpts.OpenMPSimd &&
4793 (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4794 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_target) &&
4795 Clause->getClauseKind() == OMPC_in_reduction) {
4796 // Capture taskgroup task_reduction descriptors inside the tasking regions
4797 // with the corresponding in_reduction items.
4798 auto *IRC = cast<OMPInReductionClause>(Clause);
4799 for (Expr *E : IRC->taskgroup_descriptors())
4800 if (E)
4801 MarkDeclarationsReferencedInExpr(E);
4802 }
4803 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4804 Clause->getClauseKind() == OMPC_copyprivate ||
4805 (getLangOpts().OpenMPUseTLS &&
4806 getASTContext().getTargetInfo().isTLSSupported() &&
4807 Clause->getClauseKind() == OMPC_copyin)) {
4808 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4809 // Mark all variables in private list clauses as used in inner region.
4810 for (Stmt *VarRef : Clause->children()) {
4811 if (auto *E = cast_or_null<Expr>(VarRef)) {
4812 MarkDeclarationsReferencedInExpr(E);
4813 }
4814 }
4815 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4816 } else if (isOpenMPLoopTransformationDirective(
4817 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4818 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", 4819, __extension__ __PRETTY_FUNCTION__
))
4819 "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", 4819, __extension__ __PRETTY_FUNCTION__
))
;
4820 } else if (CaptureRegions.size() > 1 ||
4821 CaptureRegions.back() != OMPD_unknown) {
4822 if (auto *C = OMPClauseWithPreInit::get(Clause))
4823 PICs.push_back(C);
4824 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4825 if (Expr *E = C->getPostUpdateExpr())
4826 MarkDeclarationsReferencedInExpr(E);
4827 }
4828 }
4829 if (Clause->getClauseKind() == OMPC_schedule)
4830 SC = cast<OMPScheduleClause>(Clause);
4831 else if (Clause->getClauseKind() == OMPC_ordered)
4832 OC = cast<OMPOrderedClause>(Clause);
4833 else if (Clause->getClauseKind() == OMPC_linear)
4834 LCs.push_back(cast<OMPLinearClause>(Clause));
4835 }
4836 // Capture allocator expressions if used.
4837 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4838 MarkDeclarationsReferencedInExpr(E);
4839 // OpenMP, 2.7.1 Loop Construct, Restrictions
4840 // The nonmonotonic modifier cannot be specified if an ordered clause is
4841 // specified.
4842 if (SC &&
4843 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4844 SC->getSecondScheduleModifier() ==
4845 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4846 OC) {
4847 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4848 ? SC->getFirstScheduleModifierLoc()
4849 : SC->getSecondScheduleModifierLoc(),
4850 diag::err_omp_simple_clause_incompatible_with_ordered)
4851 << getOpenMPClauseName(OMPC_schedule)
4852 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4853 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4854 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4855 ErrorFound = true;
4856 }
4857 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4858 // If an order(concurrent) clause is present, an ordered clause may not appear
4859 // on the same directive.
4860 if (checkOrderedOrderSpecified(*this, Clauses))
4861 ErrorFound = true;
4862 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4863 for (const OMPLinearClause *C : LCs) {
4864 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4865 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4866 }
4867 ErrorFound = true;
4868 }
4869 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4870 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4871 OC->getNumForLoops()) {
4872 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4873 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4874 ErrorFound = true;
4875 }
4876 if (ErrorFound) {
4877 return StmtError();
4878 }
4879 StmtResult SR = S;
4880 unsigned CompletedRegions = 0;
4881 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4882 // Mark all variables in private list clauses as used in inner region.
4883 // Required for proper codegen of combined directives.
4884 // TODO: add processing for other clauses.
4885 if (ThisCaptureRegion != OMPD_unknown) {
4886 for (const clang::OMPClauseWithPreInit *C : PICs) {
4887 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4888 // Find the particular capture region for the clause if the
4889 // directive is a combined one with multiple capture regions.
4890 // If the directive is not a combined one, the capture region
4891 // associated with the clause is OMPD_unknown and is generated
4892 // only once.
4893 if (CaptureRegion == ThisCaptureRegion ||
4894 CaptureRegion == OMPD_unknown) {
4895 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4896 for (Decl *D : DS->decls())
4897 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4898 }
4899 }
4900 }
4901 }
4902 if (ThisCaptureRegion == OMPD_target) {
4903 // Capture allocator traits in the target region. They are used implicitly
4904 // and, thus, are not captured by default.
4905 for (OMPClause *C : Clauses) {
4906 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4907 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4908 ++I) {
4909 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4910 if (Expr *E = D.AllocatorTraits)
4911 MarkDeclarationsReferencedInExpr(E);
4912 }
4913 continue;
4914 }
4915 }
4916 }
4917 if (ThisCaptureRegion == OMPD_parallel) {
4918 // Capture temp arrays for inscan reductions and locals in aligned
4919 // clauses.
4920 for (OMPClause *C : Clauses) {
4921 if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4922 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4923 continue;
4924 for (Expr *E : RC->copy_array_temps())
4925 MarkDeclarationsReferencedInExpr(E);
4926 }
4927 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4928 for (Expr *E : AC->varlists())
4929 MarkDeclarationsReferencedInExpr(E);
4930 }
4931 }
4932 }
4933 if (++CompletedRegions == CaptureRegions.size())
4934 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4935 SR = ActOnCapturedRegionEnd(SR.get());
4936 }
4937 return SR;
4938}
4939
4940static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4941 OpenMPDirectiveKind CancelRegion,
4942 SourceLocation StartLoc) {
4943 // CancelRegion is only needed for cancel and cancellation_point.
4944 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4945 return false;
4946
4947 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4948 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4949 return false;
4950
4951 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4952 << getOpenMPDirectiveName(CancelRegion);
4953 return true;
4954}
4955
4956static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4957 OpenMPDirectiveKind CurrentRegion,
4958 const DeclarationNameInfo &CurrentName,
4959 OpenMPDirectiveKind CancelRegion,
4960 OpenMPBindClauseKind BindKind,
4961 SourceLocation StartLoc) {
4962 if (Stack->getCurScope()) {
4963 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4964 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4965 bool NestingProhibited = false;
4966 bool CloseNesting = true;
4967 bool OrphanSeen = false;
4968 enum {
4969 NoRecommend,
4970 ShouldBeInParallelRegion,
4971 ShouldBeInOrderedRegion,
4972 ShouldBeInTargetRegion,
4973 ShouldBeInTeamsRegion,
4974 ShouldBeInLoopSimdRegion,
4975 } Recommend = NoRecommend;
4976 if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
4977 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
4978 CurrentRegion != OMPD_parallel &&
4979 !isOpenMPCombinedParallelADirective(CurrentRegion)) {
4980 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
4981 << getOpenMPDirectiveName(CurrentRegion);
4982 return true;
4983 }
4984 if (isOpenMPSimdDirective(ParentRegion) &&
4985 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4986 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4987 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4988 CurrentRegion != OMPD_scan))) {
4989 // OpenMP [2.16, Nesting of Regions]
4990 // OpenMP constructs may not be nested inside a simd region.
4991 // OpenMP [2.8.1,simd Construct, Restrictions]
4992 // An ordered construct with the simd clause is the only OpenMP
4993 // construct that can appear in the simd region.
4994 // Allowing a SIMD construct nested in another SIMD construct is an
4995 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4996 // message.
4997 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4998 // The only OpenMP constructs that can be encountered during execution of
4999 // a simd region are the atomic construct, the loop construct, the simd
5000 // construct and the ordered construct with the simd clause.
5001 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5002 ? diag::err_omp_prohibited_region_simd
5003 : diag::warn_omp_nesting_simd)
5004 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5005 return CurrentRegion != OMPD_simd;
5006 }
5007 if (ParentRegion == OMPD_atomic) {
5008 // OpenMP [2.16, Nesting of Regions]
5009 // OpenMP constructs may not be nested inside an atomic region.
5010 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5011 return true;
5012 }
5013 if (CurrentRegion == OMPD_section) {
5014 // OpenMP [2.7.2, sections Construct, Restrictions]
5015 // Orphaned section directives are prohibited. That is, the section
5016 // directives must appear within the sections construct and must not be
5017 // encountered elsewhere in the sections region.
5018 if (ParentRegion != OMPD_sections &&
5019 ParentRegion != OMPD_parallel_sections) {
5020 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5021 << (ParentRegion != OMPD_unknown)
5022 << getOpenMPDirectiveName(ParentRegion);
5023 return true;
5024 }
5025 return false;
5026 }
5027 // Allow some constructs (except teams and cancellation constructs) to be
5028 // orphaned (they could be used in functions, called from OpenMP regions
5029 // with the required preconditions).
5030 if (ParentRegion == OMPD_unknown &&
5031 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5032 CurrentRegion != OMPD_cancellation_point &&
5033 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5034 return false;
5035 if (CurrentRegion == OMPD_cancellation_point ||
5036 CurrentRegion == OMPD_cancel) {
5037 // OpenMP [2.16, Nesting of Regions]
5038 // A cancellation point construct for which construct-type-clause is
5039 // taskgroup must be nested inside a task construct. A cancellation
5040 // point construct for which construct-type-clause is not taskgroup must
5041 // be closely nested inside an OpenMP construct that matches the type
5042 // specified in construct-type-clause.
5043 // A cancel construct for which construct-type-clause is taskgroup must be
5044 // nested inside a task construct. A cancel construct for which
5045 // construct-type-clause is not taskgroup must be closely nested inside an
5046 // OpenMP construct that matches the type specified in
5047 // construct-type-clause.
5048 NestingProhibited =
5049 !((CancelRegion == OMPD_parallel &&
5050 (ParentRegion == OMPD_parallel ||
5051 ParentRegion == OMPD_target_parallel)) ||
5052 (CancelRegion == OMPD_for &&
5053 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5054 ParentRegion == OMPD_target_parallel_for ||
5055 ParentRegion == OMPD_distribute_parallel_for ||
5056 ParentRegion == OMPD_teams_distribute_parallel_for ||
5057 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5058 (CancelRegion == OMPD_taskgroup &&
5059 (ParentRegion == OMPD_task ||
5060 (SemaRef.getLangOpts().OpenMP >= 50 &&
5061 (ParentRegion == OMPD_taskloop ||
5062 ParentRegion == OMPD_master_taskloop ||
5063 ParentRegion == OMPD_masked_taskloop ||
5064 ParentRegion == OMPD_parallel_masked_taskloop ||
5065 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5066 (CancelRegion == OMPD_sections &&
5067 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5068 ParentRegion == OMPD_parallel_sections)));
5069 OrphanSeen = ParentRegion == OMPD_unknown;
5070 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5071 // OpenMP 5.1 [2.22, Nesting of Regions]
5072 // A masked region may not be closely nested inside a worksharing, loop,
5073 // atomic, task, or taskloop region.
5074 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5075 isOpenMPGenericLoopDirective(ParentRegion) ||
5076 isOpenMPTaskingDirective(ParentRegion);
5077 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5078 // OpenMP [2.16, Nesting of Regions]
5079 // A critical region may not be nested (closely or otherwise) inside a
5080 // critical region with the same name. Note that this restriction is not
5081 // sufficient to prevent deadlock.
5082 SourceLocation PreviousCriticalLoc;
5083 bool DeadLock = Stack->hasDirective(
5084 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5085 const DeclarationNameInfo &DNI,
5086 SourceLocation Loc) {
5087 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5088 PreviousCriticalLoc = Loc;
5089 return true;
5090 }
5091 return false;
5092 },
5093 false /* skip top directive */);
5094 if (DeadLock) {
5095 SemaRef.Diag(StartLoc,
5096 diag::err_omp_prohibited_region_critical_same_name)
5097 << CurrentName.getName();
5098 if (PreviousCriticalLoc.isValid())
5099 SemaRef.Diag(PreviousCriticalLoc,
5100 diag::note_omp_previous_critical_region);
5101 return true;
5102 }
5103 } else if (CurrentRegion == OMPD_barrier) {
5104 // OpenMP 5.1 [2.22, Nesting of Regions]
5105 // A barrier region may not be closely nested inside a worksharing, loop,
5106 // task, taskloop, critical, ordered, atomic, or masked region.
5107 NestingProhibited =
5108 isOpenMPWorksharingDirective(ParentRegion) ||
5109 isOpenMPGenericLoopDirective(ParentRegion) ||
5110 isOpenMPTaskingDirective(ParentRegion) ||
5111 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5112 ParentRegion == OMPD_parallel_master ||
5113 ParentRegion == OMPD_parallel_masked ||
5114 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5115 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5116 !isOpenMPParallelDirective(CurrentRegion) &&
5117 !isOpenMPTeamsDirective(CurrentRegion)) {
5118 // OpenMP 5.1 [2.22, Nesting of Regions]
5119 // A loop region that binds to a parallel region or a worksharing region
5120 // may not be closely nested inside a worksharing, loop, task, taskloop,
5121 // critical, ordered, atomic, or masked region.
5122 NestingProhibited =
5123 isOpenMPWorksharingDirective(ParentRegion) ||
5124 isOpenMPGenericLoopDirective(ParentRegion) ||
5125 isOpenMPTaskingDirective(ParentRegion) ||
5126 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5127 ParentRegion == OMPD_parallel_master ||
5128 ParentRegion == OMPD_parallel_masked ||
5129 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5130 Recommend = ShouldBeInParallelRegion;
5131 } else if (CurrentRegion == OMPD_ordered) {
5132 // OpenMP [2.16, Nesting of Regions]
5133 // An ordered region may not be closely nested inside a critical,
5134 // atomic, or explicit task region.
5135 // An ordered region must be closely nested inside a loop region (or
5136 // parallel loop region) with an ordered clause.
5137 // OpenMP [2.8.1,simd Construct, Restrictions]
5138 // An ordered construct with the simd clause is the only OpenMP construct
5139 // that can appear in the simd region.
5140 NestingProhibited = ParentRegion == OMPD_critical ||
5141 isOpenMPTaskingDirective(ParentRegion) ||
5142 !(isOpenMPSimdDirective(ParentRegion) ||
5143 Stack->isParentOrderedRegion());
5144 Recommend = ShouldBeInOrderedRegion;
5145 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5146 // OpenMP [2.16, Nesting of Regions]
5147 // If specified, a teams construct must be contained within a target
5148 // construct.
5149 NestingProhibited =
5150 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5151 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5152 ParentRegion != OMPD_target);
5153 OrphanSeen = ParentRegion == OMPD_unknown;
5154 Recommend = ShouldBeInTargetRegion;
5155 } else if (CurrentRegion == OMPD_scan) {
5156 // OpenMP [2.16, Nesting of Regions]
5157 // If specified, a teams construct must be contained within a target
5158 // construct.
5159 NestingProhibited =
5160 SemaRef.LangOpts.OpenMP < 50 ||
5161 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5162 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5163 ParentRegion != OMPD_parallel_for_simd);
5164 OrphanSeen = ParentRegion == OMPD_unknown;
5165 Recommend = ShouldBeInLoopSimdRegion;
5166 }
5167 if (!NestingProhibited &&
5168 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5169 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5170 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5171 // OpenMP [5.1, 2.22, Nesting of Regions]
5172 // distribute, distribute simd, distribute parallel worksharing-loop,
5173 // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5174 // including any parallel regions arising from combined constructs,
5175 // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5176 // only OpenMP regions that may be strictly nested inside the teams
5177 // region.
5178 //
5179 // As an extension, we permit atomic within teams as well.
5180 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5181 !isOpenMPDistributeDirective(CurrentRegion) &&
5182 CurrentRegion != OMPD_loop &&
5183 !(SemaRef.getLangOpts().OpenMPExtensions &&
5184 CurrentRegion == OMPD_atomic);
5185 Recommend = ShouldBeInParallelRegion;
5186 }
5187 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5188 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5189 // If the bind clause is present on the loop construct and binding is
5190 // teams then the corresponding loop region must be strictly nested inside
5191 // a teams region.
5192 NestingProhibited = BindKind == OMPC_BIND_teams &&
5193 ParentRegion != OMPD_teams &&
5194 ParentRegion != OMPD_target_teams;
5195 Recommend = ShouldBeInTeamsRegion;
5196 }
5197 if (!NestingProhibited &&
5198 isOpenMPNestingDistributeDirective(CurrentRegion)) {
5199 // OpenMP 4.5 [2.17 Nesting of Regions]
5200 // The region associated with the distribute construct must be strictly
5201 // nested inside a teams region
5202 NestingProhibited =
5203 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5204 Recommend = ShouldBeInTeamsRegion;
5205 }
5206 if (!NestingProhibited &&
5207 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5208 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5209 // OpenMP 4.5 [2.17 Nesting of Regions]
5210 // If a target, target update, target data, target enter data, or
5211 // target exit data construct is encountered during execution of a
5212 // target region, the behavior is unspecified.
5213 NestingProhibited = Stack->hasDirective(
5214 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5215 SourceLocation) {
5216 if (isOpenMPTargetExecutionDirective(K)) {
5217 OffendingRegion = K;
5218 return true;
5219 }
5220 return false;
5221 },
5222 false /* don't skip top directive */);
5223 CloseNesting = false;
5224 }
5225 if (NestingProhibited) {
5226 if (OrphanSeen) {
5227 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5228 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5229 } else {
5230 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5231 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5232 << Recommend << getOpenMPDirectiveName(CurrentRegion);
5233 }
5234 return true;
5235 }
5236 }
5237 return false;
5238}
5239
5240struct Kind2Unsigned {
5241 using argument_type = OpenMPDirectiveKind;
5242 unsigned operator()(argument_type DK) { return unsigned(DK); }
5243};
5244static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5245 ArrayRef<OMPClause *> Clauses,
5246 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5247 bool ErrorFound = false;
5248 unsigned NamedModifiersNumber = 0;
5249 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5250 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5251 SmallVector<SourceLocation, 4> NameModifierLoc;
5252 for (const OMPClause *C : Clauses) {
5253 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5254 // At most one if clause without a directive-name-modifier can appear on
5255 // the directive.
5256 OpenMPDirectiveKind CurNM = IC->getNameModifier();
5257 if (FoundNameModifiers[CurNM]) {
5258 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5259 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5260 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5261 ErrorFound = true;
5262 } else if (CurNM != OMPD_unknown) {
5263 NameModifierLoc.push_back(IC->getNameModifierLoc());
5264 ++NamedModifiersNumber;
5265 }
5266 FoundNameModifiers[CurNM] = IC;
5267 if (CurNM == OMPD_unknown)
5268 continue;
5269 // Check if the specified name modifier is allowed for the current
5270 // directive.
5271 // At most one if clause with the particular directive-name-modifier can
5272 // appear on the directive.
5273 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5274 S.Diag(IC->getNameModifierLoc(),
5275 diag::err_omp_wrong_if_directive_name_modifier)
5276 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5277 ErrorFound = true;
5278 }
5279 }
5280 }
5281 // If any if clause on the directive includes a directive-name-modifier then
5282 // all if clauses on the directive must include a directive-name-modifier.
5283 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5284 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5285 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5286 diag::err_omp_no_more_if_clause);
5287 } else {
5288 std::string Values;
5289 std::string Sep(", ");
5290 unsigned AllowedCnt = 0;
5291 unsigned TotalAllowedNum =
5292 AllowedNameModifiers.size() - NamedModifiersNumber;
5293 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5294 ++Cnt) {
5295 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5296 if (!FoundNameModifiers[NM]) {
5297 Values += "'";
5298 Values += getOpenMPDirectiveName(NM);
5299 Values += "'";
5300 if (AllowedCnt + 2 == TotalAllowedNum)
5301 Values += " or ";
5302 else if (AllowedCnt + 1 != TotalAllowedNum)
5303 Values += Sep;
5304 ++AllowedCnt;
5305 }
5306 }
5307 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5308 diag::err_omp_unnamed_if_clause)
5309 << (TotalAllowedNum > 1) << Values;
5310 }
5311 for (SourceLocation Loc : NameModifierLoc) {
5312 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5313 }
5314 ErrorFound = true;
5315 }
5316 return ErrorFound;
5317}
5318
5319static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5320 SourceLocation &ELoc,
5321 SourceRange &ERange,
5322 bool AllowArraySection,
5323 StringRef DiagType) {
5324 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5325 RefExpr->containsUnexpandedParameterPack())
5326 return std::make_pair(nullptr, true);
5327
5328 // OpenMP [3.1, C/C++]
5329 // A list item is a variable name.
5330 // OpenMP [2.9.3.3, Restrictions, p.1]
5331 // A variable that is part of another variable (as an array or
5332 // structure element) cannot appear in a private clause.
5333 RefExpr = RefExpr->IgnoreParens();
5334 enum {
5335 NoArrayExpr = -1,
5336 ArraySubscript = 0,
5337 OMPArraySection = 1
5338 } IsArrayExpr = NoArrayExpr;
5339 if (AllowArraySection) {
5340 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5341 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5342 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5343 Base = TempASE->getBase()->IgnoreParenImpCasts();
5344 RefExpr = Base;
5345 IsArrayExpr = ArraySubscript;
5346 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5347 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5348 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5349 Base = TempOASE->getBase()->IgnoreParenImpCasts();
5350 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5351 Base = TempASE->getBase()->IgnoreParenImpCasts();
5352 RefExpr = Base;
5353 IsArrayExpr = OMPArraySection;
5354 }
5355 }
5356 ELoc = RefExpr->getExprLoc();
5357 ERange = RefExpr->getSourceRange();
5358 RefExpr = RefExpr->IgnoreParenImpCasts();
5359 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5360 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5361 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5362 (S.getCurrentThisType().isNull() || !ME ||
5363 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5364 !isa<FieldDecl>(ME->getMemberDecl()))) {
5365 if (IsArrayExpr != NoArrayExpr) {
5366 S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5367 << IsArrayExpr << ERange;
5368 } else if (!DiagType.empty()) {
5369 unsigned DiagSelect = S.getLangOpts().CPlusPlus
5370 ? (S.getCurrentThisType().isNull() ? 1 : 2)
5371 : 0;
5372 S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5373 << DiagSelect << DiagType << ERange;
5374 } else {
5375 S.Diag(ELoc,
5376 AllowArraySection
5377 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5378 : diag::err_omp_expected_var_name_member_expr)
5379 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5380 }
5381 return std::make_pair(nullptr, false);
5382 }
5383 return std::make_pair(
5384 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5385}
5386
5387namespace {
5388/// Checks if the allocator is used in uses_allocators clause to be allowed in
5389/// target regions.
5390class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5391 DSAStackTy *S = nullptr;
5392
5393public:
5394 bool VisitDeclRefExpr(const DeclRefExpr *E) {
5395 return S->isUsesAllocatorsDecl(E->getDecl())
5396 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5397 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5398 }
5399 bool VisitStmt(const Stmt *S) {
5400 for (const Stmt *Child : S->children()) {
5401 if (Child && Visit(Child))
5402 return true;
5403 }
5404 return false;
5405 }
5406 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5407};
5408} // namespace
5409
5410static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5411 ArrayRef<OMPClause *> Clauses) {
5412 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", 5413, __extension__ __PRETTY_FUNCTION__
))
5413 "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", 5413, __extension__ __PRETTY_FUNCTION__
))
;
5414 auto AllocateRange =
5415 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5416 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5417 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5418 return isOpenMPPrivate(C->getClauseKind());
5419 });
5420 for (OMPClause *Cl : PrivateRange) {
5421 MutableArrayRef<Expr *>::iterator I, It, Et;
5422 if (Cl->getClauseKind() == OMPC_private) {
5423 auto *PC = cast<OMPPrivateClause>(Cl);
5424 I = PC->private_copies().begin();
5425 It = PC->varlist_begin();
5426 Et = PC->varlist_end();
5427 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5428 auto *PC = cast<OMPFirstprivateClause>(Cl);
5429 I = PC->private_copies().begin();
5430 It = PC->varlist_begin();
5431 Et = PC->varlist_end();
5432 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5433 auto *PC = cast<OMPLastprivateClause>(Cl);
5434 I = PC->private_copies().begin();
5435 It = PC->varlist_begin();
5436 Et = PC->varlist_end();
5437 } else if (Cl->getClauseKind() == OMPC_linear) {
5438 auto *PC = cast<OMPLinearClause>(Cl);
5439 I = PC->privates().begin();
5440 It = PC->varlist_begin();
5441 Et = PC->varlist_end();
5442 } else if (Cl->getClauseKind() == OMPC_reduction) {
5443 auto *PC = cast<OMPReductionClause>(Cl);
5444 I = PC->privates().begin();
5445 It = PC->varlist_begin();
5446 Et = PC->varlist_end();
5447 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5448 auto *PC = cast<OMPTaskReductionClause>(Cl);
5449 I = PC->privates().begin();
5450 It = PC->varlist_begin();
5451 Et = PC->varlist_end();
5452 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5453 auto *PC = cast<OMPInReductionClause>(Cl);
5454 I = PC->privates().begin();
5455 It = PC->varlist_begin();
5456 Et = PC->varlist_end();
5457 } else {
5458 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"clang/lib/Sema/SemaOpenMP.cpp", 5458)
;
5459 }
5460 for (Expr *E : llvm::make_range(It, Et)) {
5461 if (!*I) {
5462 ++I;
5463 continue;
5464 }
5465 SourceLocation ELoc;
5466 SourceRange ERange;
5467 Expr *SimpleRefExpr = E;
5468 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5469 /*AllowArraySection=*/true);
5470 DeclToCopy.try_emplace(Res.first,
5471 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5472 ++I;
5473 }
5474 }
5475 for (OMPClause *C : AllocateRange) {
5476 auto *AC = cast<OMPAllocateClause>(C);
5477 if (S.getLangOpts().OpenMP >= 50 &&
5478 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5479 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5480 AC->getAllocator()) {
5481 Expr *Allocator = AC->getAllocator();
5482 // OpenMP, 2.12.5 target Construct
5483 // Memory allocators that do not appear in a uses_allocators clause cannot
5484 // appear as an allocator in an allocate clause or be used in the target
5485 // region unless a requires directive with the dynamic_allocators clause
5486 // is present in the same compilation unit.
5487 AllocatorChecker Checker(Stack);
5488 if (Checker.Visit(Allocator))
5489 S.Diag(Allocator->getExprLoc(),
5490 diag::err_omp_allocator_not_in_uses_allocators)
5491 << Allocator->getSourceRange();
5492 }
5493 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5494 getAllocatorKind(S, Stack, AC->getAllocator());
5495 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5496 // For task, taskloop or target directives, allocation requests to memory
5497 // allocators with the trait access set to thread result in unspecified
5498 // behavior.
5499 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5500 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5501 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5502 S.Diag(AC->getAllocator()->getExprLoc(),
5503 diag::warn_omp_allocate_thread_on_task_target_directive)
5504 << getOpenMPDirectiveName(Stack->getCurrentDirective());
5505 }
5506 for (Expr *E : AC->varlists()) {
5507 SourceLocation ELoc;
5508 SourceRange ERange;
5509 Expr *SimpleRefExpr = E;
5510 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5511 ValueDecl *VD = Res.first;
5512 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5513 if (!isOpenMPPrivate(Data.CKind)) {
5514 S.Diag(E->getExprLoc(),
5515 diag::err_omp_expected_private_copy_for_allocate);
5516 continue;
5517 }
5518 VarDecl *PrivateVD = DeclToCopy[VD];
5519 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5520 AllocatorKind, AC->getAllocator()))
5521 continue;
5522 // Placeholder until allocate clause supports align modifier.
5523 Expr *Alignment = nullptr;
5524 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5525 Alignment, E->getSourceRange());
5526 }
5527 }
5528}
5529
5530namespace {
5531/// Rewrite statements and expressions for Sema \p Actions CurContext.
5532///
5533/// Used to wrap already parsed statements/expressions into a new CapturedStmt
5534/// context. DeclRefExpr used inside the new context are changed to refer to the
5535/// captured variable instead.
5536class CaptureVars : public TreeTransform<CaptureVars> {
5537 using BaseTransform = TreeTransform<CaptureVars>;
5538
5539public:
5540 CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5541
5542 bool AlwaysRebuild() { return true; }
5543};
5544} // namespace
5545
5546static VarDecl *precomputeExpr(Sema &Actions,
5547 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5548 StringRef Name) {
5549 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5550 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5551 dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5552 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5553 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5554 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5555 BodyStmts.push_back(NewDeclStmt);
5556 return NewVar;
5557}
5558
5559/// Create a closure that computes the number of iterations of a loop.
5560///
5561/// \param Actions The Sema object.
5562/// \param LogicalTy Type for the logical iteration number.
5563/// \param Rel Comparison operator of the loop condition.
5564/// \param StartExpr Value of the loop counter at the first iteration.
5565/// \param StopExpr Expression the loop counter is compared against in the loop
5566/// condition. \param StepExpr Amount of increment after each iteration.
5567///
5568/// \return Closure (CapturedStmt) of the distance calculation.
5569static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5570 BinaryOperator::Opcode Rel,
5571 Expr *StartExpr, Expr *StopExpr,
5572 Expr *StepExpr) {
5573 ASTContext &Ctx = Actions.getASTContext();
5574 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5575
5576 // Captured regions currently don't support return values, we use an
5577 // out-parameter instead. All inputs are implicit captures.
5578 // TODO: Instead of capturing each DeclRefExpr occurring in
5579 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5580 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5581 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5582 {StringRef(), QualType()}};
5583 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5584
5585 Stmt *Body;
5586 {
5587 Sema::CompoundScopeRAII CompoundScope(Actions);
5588 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5589
5590 // Get the LValue expression for the result.
5591 ImplicitParamDecl *DistParam = CS->getParam(0);
5592 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5593 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5594
5595 SmallVector<Stmt *, 4> BodyStmts;
5596
5597 // Capture all referenced variable references.
5598 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5599 // CapturedStmt, we could compute them before and capture the result, to be
5600 // used jointly with the LoopVar function.
5601 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5602 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5603 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5604 auto BuildVarRef = [&](VarDecl *VD) {
5605 return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5606 };
5607
5608 IntegerLiteral *Zero = IntegerLiteral::Create(
5609 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5610 IntegerLiteral *One = IntegerLiteral::Create(
5611 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5612 Expr *Dist;
5613 if (Rel == BO_NE) {
5614 // When using a != comparison, the increment can be +1 or -1. This can be
5615 // dynamic at runtime, so we need to check for the direction.
5616 Expr *IsNegStep = AssertSuccess(
5617 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5618
5619 // Positive increment.
5620 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5621 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5622 ForwardRange = AssertSuccess(
5623 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5624 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5625 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5626
5627 // Negative increment.
5628 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5629 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5630 BackwardRange = AssertSuccess(
5631 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5632 Expr *NegIncAmount = AssertSuccess(
5633 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5634 Expr *BackwardDist = AssertSuccess(
5635 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5636
5637 // Use the appropriate case.
5638 Dist = AssertSuccess(Actions.ActOnConditionalOp(
5639 {}, {}, IsNegStep, BackwardDist, ForwardDist));
5640 } else {
5641 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", 5642, __extension__ __PRETTY_FUNCTION__
))
5642 "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", 5642, __extension__ __PRETTY_FUNCTION__
))
;
5643
5644 // We can derive the direction from any other comparison operator. It is
5645 // non well-formed OpenMP if Step increments/decrements in the other
5646 // directions. Whether at least the first iteration passes the loop
5647 // condition.
5648 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5649 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5650
5651 // Compute the range between first and last counter value.
5652 Expr *Range;
5653 if (Rel == BO_GE || Rel == BO_GT)
5654 Range = AssertSuccess(Actions.BuildBinOp(
5655 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5656 else
5657 Range = AssertSuccess(Actions.BuildBinOp(
5658 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5659
5660 // Ensure unsigned range space.
5661 Range =
5662 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5663
5664 if (Rel == BO_LE || Rel == BO_GE) {
5665 // Add one to the range if the relational operator is inclusive.
5666 Range =
5667 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5668 }
5669
5670 // Divide by the absolute step amount. If the range is not a multiple of
5671 // the step size, rounding-up the effective upper bound ensures that the
5672 // last iteration is included.
5673 // Note that the rounding-up may cause an overflow in a temporry that
5674 // could be avoided, but would have occurred in a C-style for-loop as well.
5675 Expr *Divisor = BuildVarRef(NewStep);
5676 if (Rel == BO_GE || Rel == BO_GT)
5677 Divisor =
5678 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5679 Expr *DivisorMinusOne =
5680 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5681 Expr *RangeRoundUp = AssertSuccess(
5682 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5683 Dist = AssertSuccess(
5684 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5685
5686 // If there is not at least one iteration, the range contains garbage. Fix
5687 // to zero in this case.
5688 Dist = AssertSuccess(
5689 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5690 }
5691
5692 // Assign the result to the out-parameter.
5693 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5694 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5695 BodyStmts.push_back(ResultAssign);
5696
5697 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5698 }
5699
5700 return cast<CapturedStmt>(
5701 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5702}
5703
5704/// Create a closure that computes the loop variable from the logical iteration
5705/// number.
5706///
5707/// \param Actions The Sema object.
5708/// \param LoopVarTy Type for the loop variable used for result value.
5709/// \param LogicalTy Type for the logical iteration number.
5710/// \param StartExpr Value of the loop counter at the first iteration.
5711/// \param Step Amount of increment after each iteration.
5712/// \param Deref Whether the loop variable is a dereference of the loop
5713/// counter variable.
5714///
5715/// \return Closure (CapturedStmt) of the loop value calculation.
5716static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5717 QualType LogicalTy,
5718 DeclRefExpr *StartExpr, Expr *Step,
5719 bool Deref) {
5720 ASTContext &Ctx = Actions.getASTContext();
5721
5722 // Pass the result as an out-parameter. Passing as return value would require
5723 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5724 // invoke a copy constructor.
5725 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5726 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5727 {"Logical", LogicalTy},
5728 {StringRef(), QualType()}};
5729 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5730
5731 // Capture the initial iterator which represents the LoopVar value at the
5732 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5733 // it in every iteration, capture it by value before it is modified.
5734 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5735 bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5736 Sema::TryCapture_ExplicitByVal, {});
5737 (void)Invalid;
5738 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", 5738, __extension__ __PRETTY_FUNCTION__
))
;
5739
5740 Expr *Body;
5741 {
5742 Sema::CompoundScopeRAII CompoundScope(Actions);
5743 auto *CS = cast<CapturedDecl>(Actions.CurContext);
5744
5745 ImplicitParamDecl *TargetParam = CS->getParam(0);
5746 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5747 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5748 ImplicitParamDecl *IndvarParam = CS->getParam(1);
5749 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5750 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5751
5752 // Capture the Start expression.
5753 CaptureVars Recap(Actions);
5754 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5755 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5756
5757 Expr *Skip = AssertSuccess(
5758 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5759 // TODO: Explicitly cast to the iterator's difference_type instead of
5760 // relying on implicit conversion.
5761 Expr *Advanced =
5762 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5763
5764 if (Deref) {
5765 // For range-based for-loops convert the loop counter value to a concrete
5766 // loop variable value by dereferencing the iterator.
5767 Advanced =
5768 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5769 }
5770
5771 // Assign the result to the output parameter.
5772 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5773 BO_Assign, TargetRef, Advanced));
5774 }
5775 return cast<CapturedStmt>(
5776 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5777}
5778
5779StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5780 ASTContext &Ctx = getASTContext();
5781
5782 // Extract the common elements of ForStmt and CXXForRangeStmt:
5783 // Loop variable, repeat condition, increment
5784 Expr *Cond, *Inc;
5785 VarDecl *LIVDecl, *LUVDecl;
5786 if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5787 Stmt *Init = For->getInit();
5788 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5789 // For statement declares loop variable.
5790 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5791 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5792 // For statement reuses variable.
5793 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", 5794, __extension__ __PRETTY_FUNCTION__
))
5794 "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", 5794, __extension__ __PRETTY_FUNCTION__
))
;
5795 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5796 LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5797 } else
5798 llvm_unreachable("Cannot determine loop variable")::llvm::llvm_unreachable_internal("Cannot determine loop variable"
, "clang/lib/Sema/SemaOpenMP.cpp", 5798)
;
5799 LUVDecl = LIVDecl;
5800
5801 Cond = For->getCond();
5802 Inc = For->getInc();
5803 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5804 DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5805 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5806 LUVDecl = RangeFor->getLoopVariable();
5807
5808 Cond = RangeFor->getCond();
5809 Inc = RangeFor->getInc();
5810 } else
5811 llvm_unreachable("unhandled kind of loop")::llvm::llvm_unreachable_internal("unhandled kind of loop", "clang/lib/Sema/SemaOpenMP.cpp"
, 5811)
;
5812
5813 QualType CounterTy = LIVDecl->getType();
5814 QualType LVTy = LUVDecl->getType();
5815
5816 // Analyze the loop condition.
5817 Expr *LHS, *RHS;
5818 BinaryOperator::Opcode CondRel;
5819 Cond = Cond->IgnoreImplicit();
5820 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5821 LHS = CondBinExpr->getLHS();
5822 RHS = CondBinExpr->getRHS();
5823 CondRel = CondBinExpr->getOpcode();
5824 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5825 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", 5825, __extension__ __PRETTY_FUNCTION__
))
;
5826 LHS = CondCXXOp->getArg(0);
5827 RHS = CondCXXOp->getArg(1);
5828 switch (CondCXXOp->getOperator()) {
5829 case OO_ExclaimEqual:
5830 CondRel = BO_NE;
5831 break;
5832 case OO_Less:
5833 CondRel = BO_LT;
5834 break;
5835 case OO_LessEqual:
5836 CondRel = BO_LE;
5837 break;
5838 case OO_Greater:
5839 CondRel = BO_GT;
5840 break;
5841 case OO_GreaterEqual:
5842 CondRel = BO_GE;
5843 break;
5844 default:
5845 llvm_unreachable("unexpected iterator operator")::llvm::llvm_unreachable_internal("unexpected iterator operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5845)
;
5846 }
5847 } else
5848 llvm_unreachable("unexpected loop condition")::llvm::llvm_unreachable_internal("unexpected loop condition"
, "clang/lib/Sema/SemaOpenMP.cpp", 5848)
;
5849
5850 // Normalize such that the loop counter is on the LHS.
5851 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5852 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5853 std::swap(LHS, RHS);
5854 CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5855 }
5856 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5857
5858 // Decide the bit width for the logical iteration counter. By default use the
5859 // unsigned ptrdiff_t integer size (for iterators and pointers).
5860 // TODO: For iterators, use iterator::difference_type,
5861 // std::iterator_traits<>::difference_type or decltype(it - end).
5862 QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5863 if (CounterTy->isIntegerType()) {
5864 unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5865 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5866 }
5867
5868 // Analyze the loop increment.
5869 Expr *Step;
5870 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5871 int Direction;
5872 switch (IncUn->getOpcode()) {
5873 case UO_PreInc:
5874 case UO_PostInc:
5875 Direction = 1;
5876 break;
5877 case UO_PreDec:
5878 case UO_PostDec:
5879 Direction = -1;
5880 break;
5881 default:
5882 llvm_unreachable("unhandled unary increment operator")::llvm::llvm_unreachable_internal("unhandled unary increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5882)
;
5883 }
5884 Step = IntegerLiteral::Create(
5885 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5886 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5887 if (IncBin->getOpcode() == BO_AddAssign) {
5888 Step = IncBin->getRHS();
5889 } else if (IncBin->getOpcode() == BO_SubAssign) {
5890 Step =
5891 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5892 } else
5893 llvm_unreachable("unhandled binary increment operator")::llvm::llvm_unreachable_internal("unhandled binary increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5893)
;
5894 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5895 switch (CondCXXOp->getOperator()) {
5896 case OO_PlusPlus:
5897 Step = IntegerLiteral::Create(
5898 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5899 break;
5900 case OO_MinusMinus:
5901 Step = IntegerLiteral::Create(
5902 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5903 break;
5904 case OO_PlusEqual:
5905 Step = CondCXXOp->getArg(1);
5906 break;
5907 case OO_MinusEqual:
5908 Step = AssertSuccess(
5909 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5910 break;
5911 default:
5912 llvm_unreachable("unhandled overloaded increment operator")::llvm::llvm_unreachable_internal("unhandled overloaded increment operator"
, "clang/lib/Sema/SemaOpenMP.cpp", 5912)
;
5913 }
5914 } else
5915 llvm_unreachable("unknown increment expression")::llvm::llvm_unreachable_internal("unknown increment expression"
, "clang/lib/Sema/SemaOpenMP.cpp", 5915)
;
5916
5917 CapturedStmt *DistanceFunc =
5918 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5919 CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5920 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5921 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5922 {}, nullptr, nullptr, {}, nullptr);
5923 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5924 LoopVarFunc, LVRef);
5925}
5926
5927StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5928 // Handle a literal loop.
5929 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5930 return ActOnOpenMPCanonicalLoop(AStmt);
5931
5932 // If not a literal loop, it must be the result of a loop transformation.
5933 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5934 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", 5936, __extension__ __PRETTY_FUNCTION__
))
5935 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", 5936, __extension__ __PRETTY_FUNCTION__
))
5936 "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", 5936, __extension__ __PRETTY_FUNCTION__
))
;
5937 return LoopTransform;
5938}
5939
5940static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5941 CXXScopeSpec &MapperIdScopeSpec,
5942 const DeclarationNameInfo &MapperId,
5943 QualType Type,
5944 Expr *UnresolvedMapper);
5945
5946/// Perform DFS through the structure/class data members trying to find
5947/// member(s) with user-defined 'default' mapper and generate implicit map
5948/// clauses for such members with the found 'default' mapper.
5949static void
5950processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5951 SmallVectorImpl<OMPClause *> &Clauses) {
5952 // Check for the deault mapper for data members.
5953 if (S.getLangOpts().OpenMP < 50)
5954 return;
5955 SmallVector<OMPClause *, 4> ImplicitMaps;
5956 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5957 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5958 if (!C)
5959 continue;
5960 SmallVector<Expr *, 4> SubExprs;
5961 auto *MI = C->mapperlist_begin();
5962 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5963 ++I, ++MI) {
5964 // Expression is mapped using mapper - skip it.
5965 if (*MI)
5966 continue;
5967 Expr *E = *I;
5968 // Expression is dependent - skip it, build the mapper when it gets
5969 // instantiated.
5970 if (E->isTypeDependent() || E->isValueDependent() ||
5971 E->containsUnexpandedParameterPack())
5972 continue;
5973 // Array section - need to check for the mapping of the array section
5974 // element.
5975 QualType CanonType = E->getType().getCanonicalType();
5976 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5977 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5978 QualType BaseType =
5979 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5980 QualType ElemType;
5981 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5982 ElemType = ATy->getElementType();
5983 else
5984 ElemType = BaseType->getPointeeType();
5985 CanonType = ElemType;
5986 }
5987
5988 // DFS over data members in structures/classes.
5989 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5990 1, {CanonType, nullptr});
5991 llvm::DenseMap<const Type *, Expr *> Visited;
5992 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5993 1, {nullptr, 1});
5994 while (!Types.empty()) {
5995 QualType BaseType;
5996 FieldDecl *CurFD;
5997 std::tie(BaseType, CurFD) = Types.pop_back_val();
5998 while (ParentChain.back().second == 0)
5999 ParentChain.pop_back();
6000 --ParentChain.back().second;
6001 if (BaseType.isNull())
6002 continue;
6003 // Only structs/classes are allowed to have mappers.
6004 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6005 if (!RD)
6006 continue;
6007 auto It = Visited.find(BaseType.getTypePtr());
6008 if (It == Visited.end()) {
6009 // Try to find the associated user-defined mapper.
6010 CXXScopeSpec MapperIdScopeSpec;
6011 DeclarationNameInfo DefaultMapperId;
6012 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6013 &S.Context.Idents.get("default")));
6014 DefaultMapperId.setLoc(E->getExprLoc());
6015 ExprResult ER = buildUserDefinedMapperRef(
6016 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6017 BaseType, /*UnresolvedMapper=*/nullptr);
6018 if (ER.isInvalid())
6019 continue;
6020 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6021 }
6022 // Found default mapper.
6023 if (It->second) {
6024 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6025 VK_LValue, OK_Ordinary, E);
6026 OE->setIsUnique(/*V=*/true);
6027 Expr *BaseExpr = OE;
6028 for (const auto &P : ParentChain) {
6029 if (P.first) {
6030 BaseExpr = S.BuildMemberExpr(
6031 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6032 NestedNameSpecifierLoc(), SourceLocation(), P.first,
6033 DeclAccessPair::make(P.first, P.first->getAccess()),
6034 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6035 P.first->getType(), VK_LValue, OK_Ordinary);
6036 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6037 }
6038 }
6039 if (CurFD)
6040 BaseExpr = S.BuildMemberExpr(
6041 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6042 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6043 DeclAccessPair::make(CurFD, CurFD->getAccess()),
6044 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6045 CurFD->getType(), VK_LValue, OK_Ordinary);
6046 SubExprs.push_back(BaseExpr);
6047 continue;
6048 }
6049 // Check for the "default" mapper for data members.
6050 bool FirstIter = true;
6051 for (FieldDecl *FD : RD->fields()) {
6052 if (!FD)
6053 continue;
6054 QualType FieldTy = FD->getType();
6055 if (FieldTy.isNull() ||
6056 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6057 continue;
6058 if (FirstIter) {
6059 FirstIter = false;
6060 ParentChain.emplace_back(CurFD, 1);
6061 } else {
6062 ++ParentChain.back().second;
6063 }
6064 Types.emplace_back(FieldTy, FD);
6065 }
6066 }
6067 }
6068 if (SubExprs.empty())
6069 continue;
6070 CXXScopeSpec MapperIdScopeSpec;
6071 DeclarationNameInfo MapperId;
6072 if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6073 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6074 MapperIdScopeSpec, MapperId, C->getMapType(),
6075 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6076 SubExprs, OMPVarListLocTy()))
6077 Clauses.push_back(NewClause);
6078 }
6079}
6080
6081StmtResult Sema::ActOnOpenMPExecutableDirective(
6082 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6083 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6084 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
6085 StmtResult Res = StmtError();
6086 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6087 if (const OMPBindClause *BC =
6088 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6089 BindKind = BC->getBindKind();
6090 // First check CancelRegion which is then used in checkNestingOfRegions.
6091 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6092 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
6093 BindKind, StartLoc))
6094 return StmtError();
6095
6096 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6097 VarsWithInheritedDSAType VarsWithInheritedDSA;
6098 bool ErrorFound = false;
6099 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6100 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6101 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6102 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6103 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", 6103, __extension__ __PRETTY_FUNCTION__
))
;
6104
6105 // Check default data sharing attributes for referenced variables.
6106 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
6107 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6108 Stmt *S = AStmt;
6109 while (--ThisCaptureLevel >= 0)
6110 S = cast<CapturedStmt>(S)->getCapturedStmt();
6111 DSAChecker.Visit(S);
6112 if (!isOpenMPTargetDataManagementDirective(Kind) &&
6113 !isOpenMPTaskingDirective(Kind)) {
6114 // Visit subcaptures to generate implicit clauses for captured vars.
6115 auto *CS = cast<CapturedStmt>(AStmt);
6116 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6117 getOpenMPCaptureRegions(CaptureRegions, Kind);
6118 // Ignore outer tasking regions for target directives.
6119 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6120 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6121 DSAChecker.visitSubCaptures(CS);
6122 }
6123 if (DSAChecker.isErrorFound())
6124 return StmtError();
6125 // Generate list of implicitly defined firstprivate variables.
6126 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6127
6128 SmallVector<Expr *, 4> ImplicitFirstprivates(
6129 DSAChecker.getImplicitFirstprivate().begin(),
6130 DSAChecker.getImplicitFirstprivate().end());
6131 SmallVector<Expr *, 4> ImplicitPrivates(
6132 DSAChecker.getImplicitPrivate().begin(),
6133 DSAChecker.getImplicitPrivate().end());
6134 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6135 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6136 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6137 ImplicitMapModifiers[DefaultmapKindNum];
6138 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6139 ImplicitMapModifiersLoc[DefaultmapKindNum];
6140 // Get the original location of present modifier from Defaultmap clause.
6141 SourceLocation PresentModifierLocs[DefaultmapKindNum];
6142 for (OMPClause *C : Clauses) {
6143 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6144 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6145 PresentModifierLocs[DMC->getDefaultmapKind()] =
6146 DMC->getDefaultmapModifierLoc();
6147 }
6148 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6149 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6150 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6151 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6152 Kind, static_cast<OpenMPMapClauseKind>(I));
6153 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6154 }
6155 ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6156 DSAChecker.getImplicitMapModifier(Kind);
6157 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6158 ImplicitModifier.end());
6159 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6160 ImplicitModifier.size(), PresentModifierLocs[VC]);
6161 }
6162 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6163 for (OMPClause *C : Clauses) {
6164 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6165 for (Expr *E : IRC->taskgroup_descriptors())
6166 if (E)
6167 ImplicitFirstprivates.emplace_back(E);
6168 }
6169 // OpenMP 5.0, 2.10.1 task Construct
6170 // [detach clause]... The event-handle will be considered as if it was
6171 // specified on a firstprivate clause.
6172 if (auto *DC = dyn_cast<OMPDetachClause>(C))
6173 ImplicitFirstprivates.push_back(DC->getEventHandler());
6174 }
6175 if (!ImplicitFirstprivates.empty()) {
6176 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6177 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6178 SourceLocation())) {
6179 ClausesWithImplicit.push_back(Implicit);
6180 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6181 ImplicitFirstprivates.size();
6182 } else {
6183 ErrorFound = true;
6184 }
6185 }
6186 if (!ImplicitPrivates.empty()) {
6187 if (OMPClause *Implicit =
6188 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6189 SourceLocation(), SourceLocation())) {
6190 ClausesWithImplicit.push_back(Implicit);
6191 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6192 ImplicitPrivates.size();
6193 } else {
6194 ErrorFound = true;
6195 }
6196 }
6197 // OpenMP 5.0 [2.19.7]
6198 // If a list item appears in a reduction, lastprivate or linear
6199 // clause on a combined target construct then it is treated as
6200 // if it also appears in a map clause with a map-type of tofrom
6201 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6202 isOpenMPTargetExecutionDirective(Kind)) {
6203 SmallVector<Expr *, 4> ImplicitExprs;
6204 for (OMPClause *C : Clauses) {
6205 if (auto *RC = dyn_cast<OMPReductionClause>(C))
6206 for (Expr *E : RC->varlists())
6207 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6208 ImplicitExprs.emplace_back(E);
6209 }
6210 if (!ImplicitExprs.empty()) {
6211 ArrayRef<Expr *> Exprs = ImplicitExprs;
6212 CXXScopeSpec MapperIdScopeSpec;
6213 DeclarationNameInfo MapperId;
6214 if (OMPClause *Implicit = ActOnOpenMPMapClause(
6215 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
6216 MapperId, OMPC_MAP_tofrom,
6217 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6218 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6219 ClausesWithImplicit.emplace_back(Implicit);
6220 }
6221 }
6222 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6223 int ClauseKindCnt = -1;
6224 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6225 ++ClauseKindCnt;
6226 if (ImplicitMap.empty())
6227 continue;
6228 CXXScopeSpec MapperIdScopeSpec;
6229 DeclarationNameInfo MapperId;
6230 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6231 if (OMPClause *Implicit = ActOnOpenMPMapClause(
6232 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6233 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6234 SourceLocation(), SourceLocation(), ImplicitMap,
6235 OMPVarListLocTy())) {
6236 ClausesWithImplicit.emplace_back(Implicit);
6237 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6238 ImplicitMap.size();
6239 } else {
6240 ErrorFound = true;
6241 }
6242 }
6243 }
6244 // Build expressions for implicit maps of data members with 'default'
6245 // mappers.
6246 if (LangOpts.OpenMP >= 50)
6247 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6248 ClausesWithImplicit);
6249 }
6250
6251 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6252 switch (Kind) {
6253 case OMPD_parallel:
6254 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6255 EndLoc);
6256 AllowedNameModifiers.push_back(OMPD_parallel);
6257 break;
6258 case OMPD_simd:
6259 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6260 VarsWithInheritedDSA);
6261 if (LangOpts.OpenMP >= 50)
6262 AllowedNameModifiers.push_back(OMPD_simd);
6263 break;
6264 case OMPD_tile:
6265 Res =
6266 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6267 break;
6268 case OMPD_unroll:
6269 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6270 EndLoc);
6271 break;
6272 case OMPD_for:
6273 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6274 VarsWithInheritedDSA);
6275 break;
6276 case OMPD_for_simd:
6277 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6278 EndLoc, VarsWithInheritedDSA);
6279 if (LangOpts.OpenMP >= 50)
6280 AllowedNameModifiers.push_back(OMPD_simd);
6281 break;
6282 case OMPD_sections:
6283 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6284 EndLoc);
6285 break;
6286 case OMPD_section:
6287 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", 6288, __extension__ __PRETTY_FUNCTION__
))
6288 "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", 6288, __extension__ __PRETTY_FUNCTION__
))
;
6289 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6290 break;
6291 case OMPD_single:
6292 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6293 EndLoc);
6294 break;
6295 case OMPD_master:
6296 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", 6297, __extension__ __PRETTY_FUNCTION__
))
6297 "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", 6297, __extension__ __PRETTY_FUNCTION__
))
;
6298 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6299 break;
6300 case OMPD_masked:
6301 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6302 EndLoc);
6303 break;
6304 case OMPD_critical:
6305 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6306 StartLoc, EndLoc);
6307 break;
6308 case OMPD_parallel_for:
6309 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6310 EndLoc, VarsWithInheritedDSA);
6311 AllowedNameModifiers.push_back(OMPD_parallel);
6312 break;
6313 case OMPD_parallel_for_simd:
6314 Res = ActOnOpenMPParallelForSimdDirective(
6315 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6316 AllowedNameModifiers.push_back(OMPD_parallel);
6317 if (LangOpts.OpenMP >= 50)
6318 AllowedNameModifiers.push_back(OMPD_simd);
6319 break;
6320 case OMPD_parallel_master:
6321 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6322 StartLoc, EndLoc);
6323 AllowedNameModifiers.push_back(OMPD_parallel);
6324 break;
6325 case OMPD_parallel_masked:
6326 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6327 StartLoc, EndLoc);
6328 AllowedNameModifiers.push_back(OMPD_parallel);
6329 break;
6330 case OMPD_parallel_sections:
6331 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6332 StartLoc, EndLoc);
6333 AllowedNameModifiers.push_back(OMPD_parallel);
6334 break;
6335 case OMPD_task:
6336 Res =
6337 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6338 AllowedNameModifiers.push_back(OMPD_task);
6339 break;
6340 case OMPD_taskyield:
6341 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", 6342, __extension__ __PRETTY_FUNCTION__
))
6342 "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", 6342, __extension__ __PRETTY_FUNCTION__
))
;
6343 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", 6344, __extension__ __PRETTY_FUNCTION__
))
6344 "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", 6344, __extension__ __PRETTY_FUNCTION__
))
;
6345 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6346 break;
6347 case OMPD_error:
6348 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp error' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp error' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6349, __extension__ __PRETTY_FUNCTION__
))
6349 "No associated statement allowed for 'omp error' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp error' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp error' directive\""
, "clang/lib/Sema/SemaOpenMP.cpp", 6349, __extension__ __PRETTY_FUNCTION__
))
;
6350 Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6351 break;
6352 case OMPD_barrier:
6353 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", 6354, __extension__ __PRETTY_FUNCTION__
))
6354 "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", 6354, __extension__ __PRETTY_FUNCTION__
))
;
6355 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", 6356, __extension__ __PRETTY_FUNCTION__
))
6356 "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", 6356, __extension__ __PRETTY_FUNCTION__
))
;
6357 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6358 break;
6359 case OMPD_taskwait:
6360 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", 6361, __extension__ __PRETTY_FUNCTION__
))
6361 "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", 6361, __extension__ __PRETTY_FUNCTION__
))
;
6362 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6363 break;
6364 case OMPD_taskgroup:
6365 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6366 EndLoc);
6367 break;
6368 case OMPD_flush:
6369 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", 6370, __extension__ __PRETTY_FUNCTION__
))
6370 "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", 6370, __extension__ __PRETTY_FUNCTION__
))
;
6371 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6372 break;
6373 case OMPD_depobj:
6374 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", 6375, __extension__ __PRETTY_FUNCTION__
))
6375 "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", 6375, __extension__ __PRETTY_FUNCTION__
))
;
6376 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6377 break;
6378 case OMPD_scan:
6379 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", 6380, __extension__ __PRETTY_FUNCTION__
))
6380 "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", 6380, __extension__ __PRETTY_FUNCTION__
))
;
6381 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6382 break;
6383 case OMPD_ordered:
6384 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6385 EndLoc);
6386 break;
6387 case OMPD_atomic:
6388 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6389 EndLoc);
6390 break;
6391 case OMPD_teams:
6392 Res =
6393 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6394 break;
6395 case OMPD_target:
6396 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6397 EndLoc);
6398 AllowedNameModifiers.push_back(OMPD_target);
6399 break;
6400 case OMPD_target_parallel:
6401 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6402 StartLoc, EndLoc);
6403 AllowedNameModifiers.push_back(OMPD_target);
6404 AllowedNameModifiers.push_back(OMPD_parallel);
6405 break;
6406 case OMPD_target_parallel_for:
6407 Res = ActOnOpenMPTargetParallelForDirective(
6408 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6409 AllowedNameModifiers.push_back(OMPD_target);
6410 AllowedNameModifiers.push_back(OMPD_parallel);
6411 break;
6412 case OMPD_cancellation_point:
6413 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", 6414, __extension__ __PRETTY_FUNCTION__
))
6414 "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", 6414, __extension__ __PRETTY_FUNCTION__
))
;
6415 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", 6416, __extension__ __PRETTY_FUNCTION__
))
6416 "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", 6416, __extension__ __PRETTY_FUNCTION__
))
;
6417 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6418 break;
6419 case OMPD_cancel:
6420 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", 6421, __extension__ __PRETTY_FUNCTION__
))
6421 "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", 6421, __extension__ __PRETTY_FUNCTION__
))
;
6422 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6423 CancelRegion);
6424 AllowedNameModifiers.push_back(OMPD_cancel);
6425 break;
6426 case OMPD_target_data:
6427 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6428 EndLoc);
6429 AllowedNameModifiers.push_back(OMPD_target_data);
6430 break;
6431 case OMPD_target_enter_data:
6432 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6433 EndLoc, AStmt);
6434 AllowedNameModifiers.push_back(OMPD_target_enter_data);
6435 break;
6436 case OMPD_target_exit_data:
6437 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6438 EndLoc, AStmt);
6439 AllowedNameModifiers.push_back(OMPD_target_exit_data);
6440 break;
6441 case OMPD_taskloop:
6442 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6443 EndLoc, VarsWithInheritedDSA);
6444 AllowedNameModifiers.push_back(OMPD_taskloop);
6445 break;
6446 case OMPD_taskloop_simd:
6447 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6448 EndLoc, VarsWithInheritedDSA);
6449 AllowedNameModifiers.push_back(OMPD_taskloop);
6450 if (LangOpts.OpenMP >= 50)
6451 AllowedNameModifiers.push_back(OMPD_simd);
6452 break;
6453 case OMPD_master_taskloop:
6454 Res = ActOnOpenMPMasterTaskLoopDirective(
6455 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6456 AllowedNameModifiers.push_back(OMPD_taskloop);
6457 break;
6458 case OMPD_masked_taskloop:
6459 Res = ActOnOpenMPMaskedTaskLoopDirective(
6460 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6461 AllowedNameModifiers.push_back(OMPD_taskloop);
6462 break;
6463 case OMPD_master_taskloop_simd:
6464 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6465 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6466 AllowedNameModifiers.push_back(OMPD_taskloop);
6467 if (LangOpts.OpenMP >= 50)
6468 AllowedNameModifiers.push_back(OMPD_simd);
6469 break;
6470 case OMPD_masked_taskloop_simd:
6471 Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6472 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6473 if (LangOpts.OpenMP >= 51) {
6474 AllowedNameModifiers.push_back(OMPD_taskloop);
6475 AllowedNameModifiers.push_back(OMPD_simd);
6476 }
6477 break;
6478 case OMPD_parallel_master_taskloop:
6479 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6480 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6481 AllowedNameModifiers.push_back(OMPD_taskloop);
6482 AllowedNameModifiers.push_back(OMPD_parallel);
6483 break;
6484 case OMPD_parallel_masked_taskloop:
6485 Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6486 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6487 if (LangOpts.OpenMP >= 51) {
6488 AllowedNameModifiers.push_back(OMPD_taskloop);
6489 AllowedNameModifiers.push_back(OMPD_parallel);
6490 }
6491 break;
6492 case OMPD_parallel_master_taskloop_simd:
6493 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6494 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6495 AllowedNameModifiers.push_back(OMPD_taskloop);
6496 AllowedNameModifiers.push_back(OMPD_parallel);
6497 if (LangOpts.OpenMP >= 50)
6498 AllowedNameModifiers.push_back(OMPD_simd);
6499 break;
6500 case OMPD_parallel_masked_taskloop_simd:
6501 Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6502 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6503 if (LangOpts.OpenMP >= 51) {
6504 AllowedNameModifiers.push_back(OMPD_taskloop);
6505 AllowedNameModifiers.push_back(OMPD_parallel);
6506 AllowedNameModifiers.push_back(OMPD_simd);
6507 }
6508 break;
6509 case OMPD_distribute:
6510 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6511 EndLoc, VarsWithInheritedDSA);
6512 break;
6513 case OMPD_target_update:
6514 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6515 EndLoc, AStmt);
6516 AllowedNameModifiers.push_back(OMPD_target_update);
6517 break;
6518 case OMPD_distribute_parallel_for:
6519 Res = ActOnOpenMPDistributeParallelForDirective(
6520 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6521 AllowedNameModifiers.push_back(OMPD_parallel);
6522 break;
6523 case OMPD_distribute_parallel_for_simd:
6524 Res = ActOnOpenMPDistributeParallelForSimdDirective(
6525 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6526 AllowedNameModifiers.push_back(OMPD_parallel);
6527 if (LangOpts.OpenMP >= 50)
6528 AllowedNameModifiers.push_back(OMPD_simd);
6529 break;
6530 case OMPD_distribute_simd:
6531 Res = ActOnOpenMPDistributeSimdDirective(
6532 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6533 if (LangOpts.OpenMP >= 50)
6534 AllowedNameModifiers.push_back(OMPD_simd);
6535 break;
6536 case OMPD_target_parallel_for_simd:
6537 Res = ActOnOpenMPTargetParallelForSimdDirective(
6538 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6539 AllowedNameModifiers.push_back(OMPD_target);
6540 AllowedNameModifiers.push_back(OMPD_parallel);
6541 if (LangOpts.OpenMP >= 50)
6542 AllowedNameModifiers.push_back(OMPD_simd);
6543 break;
6544 case OMPD_target_simd:
6545 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6546 EndLoc, VarsWithInheritedDSA);
6547 AllowedNameModifiers.push_back(OMPD_target);
6548 if (LangOpts.OpenMP >= 50)
6549 AllowedNameModifiers.push_back(OMPD_simd);
6550 break;
6551 case OMPD_teams_distribute:
6552 Res = ActOnOpenMPTeamsDistributeDirective(
6553 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6554 break;
6555 case OMPD_teams_distribute_simd:
6556 Res = ActOnOpenMPTeamsDistributeSimdDirective(
6557 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6558 if (LangOpts.OpenMP >= 50)
6559 AllowedNameModifiers.push_back(OMPD_simd);
6560 break;
6561 case OMPD_teams_distribute_parallel_for_simd:
6562 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6563 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6564 AllowedNameModifiers.push_back(OMPD_parallel);
6565 if (LangOpts.OpenMP >= 50)
6566 AllowedNameModifiers.push_back(OMPD_simd);
6567 break;
6568 case OMPD_teams_distribute_parallel_for:
6569 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6570 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6571 AllowedNameModifiers.push_back(OMPD_parallel);
6572 break;
6573 case OMPD_target_teams:
6574 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6575 EndLoc);
6576 AllowedNameModifiers.push_back(OMPD_target);
6577 break;
6578 case OMPD_target_teams_distribute:
6579 Res = ActOnOpenMPTargetTeamsDistributeDirective(
6580 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6581 AllowedNameModifiers.push_back(OMPD_target);
6582 break;
6583 case OMPD_target_teams_distribute_parallel_for:
6584 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6585 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6586 AllowedNameModifiers.push_back(OMPD_target);
6587 AllowedNameModifiers.push_back(OMPD_parallel);
6588 break;
6589 case OMPD_target_teams_distribute_parallel_for_simd:
6590 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6591 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6592 AllowedNameModifiers.push_back(OMPD_target);
6593 AllowedNameModifiers.push_back(OMPD_parallel);
6594 if (LangOpts.OpenMP >= 50)
6595 AllowedNameModifiers.push_back(OMPD_simd);
6596 break;
6597 case OMPD_target_teams_distribute_simd:
6598 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6599 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6600 AllowedNameModifiers.push_back(OMPD_target);
6601 if (LangOpts.OpenMP >= 50)
6602 AllowedNameModifiers.push_back(OMPD_simd);
6603 break;
6604 case OMPD_interop:
6605 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", 6606, __extension__ __PRETTY_FUNCTION__
))
6606 "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", 6606, __extension__ __PRETTY_FUNCTION__
))
;
6607 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6608 break;
6609 case OMPD_dispatch:
6610 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6611 EndLoc);
6612 break;
6613 case OMPD_loop:
6614 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6615 EndLoc, VarsWithInheritedDSA);
6616 break;
6617 case OMPD_teams_loop:
6618 Res = ActOnOpenMPTeamsGenericLoopDirective(
6619 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6620 break;
6621 case OMPD_target_teams_loop:
6622 Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6623 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6624 break;
6625 case OMPD_parallel_loop:
6626 Res = ActOnOpenMPParallelGenericLoopDirective(
6627 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6628 break;
6629 case OMPD_target_parallel_loop:
6630 Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6631 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6632 break;
6633 case OMPD_declare_target:
6634 case OMPD_end_declare_target:
6635 case OMPD_threadprivate:
6636 case OMPD_allocate:
6637 case OMPD_declare_reduction:
6638 case OMPD_declare_mapper:
6639 case OMPD_declare_simd:
6640 case OMPD_requires:
6641 case OMPD_declare_variant:
6642 case OMPD_begin_declare_variant:
6643 case OMPD_end_declare_variant:
6644 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "clang/lib/Sema/SemaOpenMP.cpp", 6644)
;
6645 case OMPD_unknown:
6646 default:
6647 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 6647)
;
6648 }
6649
6650 ErrorFound = Res.isInvalid() || ErrorFound;
6651
6652 // Check variables in the clauses if default(none) or
6653 // default(firstprivate) was specified.
6654 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6655 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_private ||
6656 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6657 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
6658 for (OMPClause *C : Clauses) {
6659 switch (C->getClauseKind()) {
6660 case OMPC_num_threads:
6661 case OMPC_dist_schedule:
6662 // Do not analyse if no parent teams directive.
6663 if (isOpenMPTeamsDirective(Kind))
6664 break;
6665 continue;
6666 case OMPC_if:
6667 if (isOpenMPTeamsDirective(Kind) &&
6668 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6669 break;
6670 if (isOpenMPParallelDirective(Kind) &&
6671 isOpenMPTaskLoopDirective(Kind) &&
6672 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6673 break;
6674 continue;
6675 case OMPC_schedule:
6676 case OMPC_detach:
6677 break;
6678 case OMPC_grainsize:
6679 case OMPC_num_tasks:
6680 case OMPC_final:
6681 case OMPC_priority:
6682 case OMPC_novariants:
6683 case OMPC_nocontext:
6684 // Do not analyze if no parent parallel directive.
6685 if (isOpenMPParallelDirective(Kind))
6686 break;
6687 continue;
6688 case OMPC_ordered:
6689 case OMPC_device:
6690 case OMPC_num_teams:
6691 case OMPC_thread_limit:
6692 case OMPC_hint:
6693 case OMPC_collapse:
6694 case OMPC_safelen:
6695 case OMPC_simdlen:
6696 case OMPC_sizes:
6697 case OMPC_default:
6698 case OMPC_proc_bind:
6699 case OMPC_private:
6700 case OMPC_firstprivate:
6701 case OMPC_lastprivate:
6702 case OMPC_shared:
6703 case OMPC_reduction:
6704 case OMPC_task_reduction:
6705 case OMPC_in_reduction:
6706 case OMPC_linear:
6707 case OMPC_aligned:
6708 case OMPC_copyin:
6709 case OMPC_copyprivate:
6710 case OMPC_nowait:
6711 case OMPC_untied:
6712 case OMPC_mergeable:
6713 case OMPC_allocate:
6714 case OMPC_read:
6715 case OMPC_write:
6716 case OMPC_update:
6717 case OMPC_capture:
6718 case OMPC_compare:
6719 case OMPC_seq_cst:
6720 case OMPC_acq_rel:
6721 case OMPC_acquire:
6722 case OMPC_release:
6723 case OMPC_relaxed:
6724 case OMPC_depend:
6725 case OMPC_threads:
6726 case OMPC_simd:
6727 case OMPC_map:
6728 case OMPC_nogroup:
6729 case OMPC_defaultmap:
6730 case OMPC_to:
6731 case OMPC_from:
6732 case OMPC_use_device_ptr:
6733 case OMPC_use_device_addr:
6734 case OMPC_is_device_ptr:
6735 case OMPC_has_device_addr:
6736 case OMPC_nontemporal:
6737 case OMPC_order:
6738 case OMPC_destroy:
6739 case OMPC_inclusive:
6740 case OMPC_exclusive:
6741 case OMPC_uses_allocators:
6742 case OMPC_affinity:
6743 case OMPC_bind:
6744 case OMPC_filter:
6745 continue;
6746 case OMPC_allocator:
6747 case OMPC_flush:
6748 case OMPC_depobj:
6749 case OMPC_threadprivate:
6750 case OMPC_uniform:
6751 case OMPC_unknown:
6752 case OMPC_unified_address:
6753 case OMPC_unified_shared_memory:
6754 case OMPC_reverse_offload:
6755 case OMPC_dynamic_allocators:
6756 case OMPC_atomic_default_mem_order:
6757 case OMPC_device_type:
6758 case OMPC_match:
6759 case OMPC_when:
6760 case OMPC_at:
6761 case OMPC_severity:
6762 case OMPC_message:
6763 default:
6764 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "clang/lib/Sema/SemaOpenMP.cpp"
, 6764)
;
6765 }
6766 for (Stmt *CC : C->children()) {
6767 if (CC)
6768 DSAChecker.Visit(CC);
6769 }
6770 }
6771 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6772 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6773 }
6774 for (const auto &P : VarsWithInheritedDSA) {
6775 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6776 continue;
6777 ErrorFound = true;
6778 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
6779 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_private ||
6780 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
6781 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6782 << P.first << P.second->getSourceRange();
6783 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6784 } else if (getLangOpts().OpenMP >= 50) {
6785 Diag(P.second->getExprLoc(),
6786 diag::err_omp_defaultmap_no_attr_for_variable)
6787 << P.first << P.second->getSourceRange();
6788 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
6789 diag::note_omp_defaultmap_attr_none);
6790 }
6791 }
6792
6793 if (!AllowedNameModifiers.empty())
6794 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6795 ErrorFound;
6796
6797 if (ErrorFound)
6798 return StmtError();
6799
6800 if (!CurContext->isDependentContext() &&
6801 isOpenMPTargetExecutionDirective(Kind) &&
6802 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6803 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6804 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6805 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6806 // Register target to DSA Stack.
6807 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
6808 }
6809
6810 return Res;
6811}
6812
6813Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6814 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6815 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6816 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6817 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6818 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", 6818, __extension__ __PRETTY_FUNCTION__
))
;
6819 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", 6819, __extension__ __PRETTY_FUNCTION__
))
;
6820 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"
, 6820, __extension__ __PRETTY_FUNCTION__))
;
6821 if (!DG || DG.get().isNull())
6822 return DeclGroupPtrTy();
6823
6824 const int SimdId = 0;
6825 if (!DG.get().isSingleDecl()) {
6826 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6827 << SimdId;
6828 return DG;
6829 }
6830 Decl *ADecl = DG.get().getSingleDecl();
6831 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6832 ADecl = FTD->getTemplatedDecl();
6833
6834 auto *FD = dyn_cast<FunctionDecl>(ADecl);
6835 if (!FD) {
6836 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6837 return DeclGroupPtrTy();
6838 }
6839
6840 // OpenMP [2.8.2, declare simd construct, Description]
6841 // The parameter of the simdlen clause must be a constant positive integer
6842 // expression.
6843 ExprResult SL;
6844 if (Simdlen)
6845 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6846 // OpenMP [2.8.2, declare simd construct, Description]
6847 // The special this pointer can be used as if was one of the arguments to the
6848 // function in any of the linear, aligned, or uniform clauses.
6849 // The uniform clause declares one or more arguments to have an invariant
6850 // value for all concurrent invocations of the function in the execution of a
6851 // single SIMD loop.
6852 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6853 const Expr *UniformedLinearThis = nullptr;
6854 for (const Expr *E : Uniforms) {
6855 E = E->IgnoreParenImpCasts();
6856 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6857 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6858 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6859 FD->getParamDecl(PVD->getFunctionScopeIndex())
6860 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6861 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6862 continue;
6863 }
6864 if (isa<CXXThisExpr>(E)) {
6865 UniformedLinearThis = E;
6866 continue;
6867 }
6868 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6869 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6870 }
6871 // OpenMP [2.8.2, declare simd construct, Description]
6872 // The aligned clause declares that the object to which each list item points
6873 // is aligned to the number of bytes expressed in the optional parameter of
6874 // the aligned clause.
6875 // The special this pointer can be used as if was one of the arguments to the
6876 // function in any of the linear, aligned, or uniform clauses.
6877 // The type of list items appearing in the aligned clause must be array,
6878 // pointer, reference to array, or reference to pointer.
6879 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6880 const Expr *AlignedThis = nullptr;
6881 for (const Expr *E : Aligneds) {
6882 E = E->IgnoreParenImpCasts();
6883 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6884 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6885 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6886 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6887 FD->getParamDecl(PVD->getFunctionScopeIndex())
6888 ->getCanonicalDecl() == CanonPVD) {
6889 // OpenMP [2.8.1, simd construct, Restrictions]
6890 // A list-item cannot appear in more than one aligned clause.
6891 if (AlignedArgs.count(CanonPVD) > 0) {
6892 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6893 << 1 << getOpenMPClauseName(OMPC_aligned)
6894 << E->getSourceRange();
6895 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6896 diag::note_omp_explicit_dsa)
6897 << getOpenMPClauseName(OMPC_aligned);
6898 continue;
6899 }
6900 AlignedArgs[CanonPVD] = E;
6901 QualType QTy = PVD->getType()
6902 .getNonReferenceType()
6903 .getUnqualifiedType()
6904 .getCanonicalType();
6905 const Type *Ty = QTy.getTypePtrOrNull();
6906 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6907 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6908 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6909 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6910 }
6911 continue;
6912 }
6913 }
6914 if (isa<CXXThisExpr>(E)) {
6915 if (AlignedThis) {
6916 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6917 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6918 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6919 << getOpenMPClauseName(OMPC_aligned);
6920 }
6921 AlignedThis = E;
6922 continue;
6923 }
6924 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6925 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6926 }
6927 // The optional parameter of the aligned clause, alignment, must be a constant
6928 // positive integer expression. If no optional parameter is specified,
6929 // implementation-defined default alignments for SIMD instructions on the
6930 // target platforms are assumed.
6931 SmallVector<const Expr *, 4> NewAligns;
6932 for (Expr *E : Alignments) {
6933 ExprResult Align;
6934 if (E)
6935 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6936 NewAligns.push_back(Align.get());
6937 }
6938 // OpenMP [2.8.2, declare simd construct, Description]
6939 // The linear clause declares one or more list items to be private to a SIMD
6940 // lane and to have a linear relationship with respect to the iteration space
6941 // of a loop.
6942 // The special this pointer can be used as if was one of the arguments to the
6943 // function in any of the linear, aligned, or uniform clauses.
6944 // When a linear-step expression is specified in a linear clause it must be
6945 // either a constant integer expression or an integer-typed parameter that is
6946 // specified in a uniform clause on the directive.
6947 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6948 const bool IsUniformedThis = UniformedLinearThis != nullptr;
6949 auto MI = LinModifiers.begin();
6950 for (const Expr *E : Linears) {
6951 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6952 ++MI;
6953 E = E->IgnoreParenImpCasts();
6954 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6955 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6956 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6957 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6958 FD->getParamDecl(PVD->getFunctionScopeIndex())
6959 ->getCanonicalDecl() == CanonPVD) {
6960 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6961 // A list-item cannot appear in more than one linear clause.
6962 if (LinearArgs.count(CanonPVD) > 0) {
6963 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6964 << getOpenMPClauseName(OMPC_linear)
6965 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6966 Diag(LinearArgs[CanonPVD]->getExprLoc(),
6967 diag::note_omp_explicit_dsa)
6968 << getOpenMPClauseName(OMPC_linear);
6969 continue;
6970 }
6971 // Each argument can appear in at most one uniform or linear clause.
6972 if (UniformedArgs.count(CanonPVD) > 0) {
6973 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6974 << getOpenMPClauseName(OMPC_linear)
6975 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6976 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6977 diag::note_omp_explicit_dsa)
6978 << getOpenMPClauseName(OMPC_uniform);
6979 continue;
6980 }
6981 LinearArgs[CanonPVD] = E;
6982 if (E->isValueDependent() || E->isTypeDependent() ||
6983 E->isInstantiationDependent() ||
6984 E->containsUnexpandedParameterPack())
6985 continue;
6986 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6987 PVD->getOriginalType(),
6988 /*IsDeclareSimd=*/true);
6989 continue;
6990 }
6991 }
6992 if (isa<CXXThisExpr>(E)) {
6993 if (UniformedLinearThis) {
6994 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6995 << getOpenMPClauseName(OMPC_linear)
6996 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6997 << E->getSourceRange();
6998 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6999 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7000 : OMPC_linear);
7001 continue;
7002 }
7003 UniformedLinearThis = E;
7004 if (E->isValueDependent() || E->isTypeDependent() ||
7005 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7006 continue;
7007 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7008 E->getType(), /*IsDeclareSimd=*/true);
7009 continue;
7010 }
7011 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7012 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7013 }
7014 Expr *Step = nullptr;
7015 Expr *NewStep = nullptr;
7016 SmallVector<Expr *, 4> NewSteps;
7017 for (Expr *E : Steps) {
7018 // Skip the same step expression, it was checked already.
7019 if (Step == E || !E) {
7020 NewSteps.push_back(E ? NewStep : nullptr);
7021 continue;
7022 }
7023 Step = E;
7024 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7025 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7026 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7027 if (UniformedArgs.count(CanonPVD) == 0) {
7028 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7029 << Step->getSourceRange();
7030 } else if (E->isValueDependent() || E->isTypeDependent() ||
7031 E->isInstantiationDependent() ||
7032 E->containsUnexpandedParameterPack() ||
7033 CanonPVD->getType()->hasIntegerRepresentation()) {
7034 NewSteps.push_back(Step);
7035 } else {
7036 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7037 << Step->getSourceRange();
7038 }
7039 continue;
7040 }
7041 NewStep = Step;
7042 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7043 !Step->isInstantiationDependent() &&
7044 !Step->containsUnexpandedParameterPack()) {
7045 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7046 .get();
7047 if (NewStep)
7048 NewStep =
7049 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7050 }
7051 NewSteps.push_back(NewStep);
7052 }
7053 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7054 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7055 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7056 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7057 const_cast<Expr **>(Linears.data()), Linears.size(),
7058 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7059 NewSteps.data(), NewSteps.size(), SR);
7060 ADecl->addAttr(NewAttr);
7061 return DG;
7062}
7063
7064static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7065 QualType NewType) {
7066 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", 7067, __extension__ __PRETTY_FUNCTION__
))
7067 "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", 7067, __extension__ __PRETTY_FUNCTION__
))
;
7068 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", 7069, __extension__ __PRETTY_FUNCTION__
))
7069 "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", 7069, __extension__ __PRETTY_FUNCTION__
))
;
7070 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", 7071, __extension__ __PRETTY_FUNCTION__
))
7071 "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", 7071, __extension__ __PRETTY_FUNCTION__
))
;
7072 // Synthesize parameters with the same types.
7073 FD->setType(NewType);
7074 SmallVector<ParmVarDecl *, 16> Params;
7075 for (const ParmVarDecl *P : FDWithProto->parameters()) {
7076 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7077 SourceLocation(), nullptr, P->getType(),
7078 /*TInfo=*/nullptr, SC_None, nullptr);
7079 Param->setScopeInfo(0, Params.size());
7080 Param->setImplicit();
7081 Params.push_back(Param);
7082 }
7083
7084 FD->setParams(Params);
7085}
7086
7087void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7088 if (D->isInvalidDecl())
7089 return;
7090 FunctionDecl *FD = nullptr;
7091 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7092 FD = UTemplDecl->getTemplatedDecl();
7093 else
7094 FD = cast<FunctionDecl>(D);
7095 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", 7095, __extension__ __PRETTY_FUNCTION__
))
;
7096
7097 // If we are instantiating templates we do *not* apply scoped assumptions but
7098 // only global ones. We apply scoped assumption to the template definition
7099 // though.
7100 if (!inTemplateInstantiation()) {
7101 for (AssumptionAttr *AA : OMPAssumeScoped)
7102 FD->addAttr(AA);
7103 }
7104 for (AssumptionAttr *AA : OMPAssumeGlobal)
7105 FD->addAttr(AA);
7106}
7107
7108Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7109 : TI(&TI), NameSuffix(TI.getMangledName()) {}
7110
7111void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7112 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7113 SmallVectorImpl<FunctionDecl *> &Bases) {
7114 if (!D.getIdentifier())
7115 return;
7116
7117 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7118
7119 // Template specialization is an extension, check if we do it.
7120 bool IsTemplated = !TemplateParamLists.empty();
7121 if (IsTemplated &
7122 !DVScope.TI->isExtensionActive(
7123 llvm::omp::TraitProperty::implementation_extension_allow_templates))
7124 return;
7125
7126 IdentifierInfo *BaseII = D.getIdentifier();
7127 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7128 LookupOrdinaryName);
7129 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7130
7131 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7132 QualType FType = TInfo->getType();
7133
7134 bool IsConstexpr =
7135 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7136 bool IsConsteval =
7137 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7138
7139 for (auto *Candidate : Lookup) {
7140 auto *CandidateDecl = Candidate->getUnderlyingDecl();
7141 FunctionDecl *UDecl = nullptr;
7142 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7143 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7144 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7145 UDecl = FTD->getTemplatedDecl();
7146 } else if (!IsTemplated)
7147 UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7148 if (!UDecl)
7149 continue;
7150
7151 // Don't specialize constexpr/consteval functions with
7152 // non-constexpr/consteval functions.
7153 if (UDecl->isConstexpr() && !IsConstexpr)
7154 continue;
7155 if (UDecl->isConsteval() && !IsConsteval)
7156 continue;
7157
7158 QualType UDeclTy = UDecl->getType();
7159 if (!UDeclTy->isDependentType()) {
7160 QualType NewType = Context.mergeFunctionTypes(
7161 FType, UDeclTy, /* OfBlockPointer */ false,
7162 /* Unqualified */ false, /* AllowCXX */ true);
7163 if (NewType.isNull())
7164 continue;
7165 }
7166
7167 // Found a base!
7168 Bases.push_back(UDecl);
7169 }
7170
7171 bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7172 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7173 // If no base was found we create a declaration that we use as base.
7174 if (Bases.empty() && UseImplicitBase) {
7175 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7176 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7177 BaseD->setImplicit(true);
7178 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7179 Bases.push_back(BaseTemplD->getTemplatedDecl());
7180 else
7181 Bases.push_back(cast<FunctionDecl>(BaseD));
7182 }
7183
7184 std::string MangledName;
7185 MangledName += D.getIdentifier()->getName();
7186 MangledName += getOpenMPVariantManglingSeparatorStr();
7187 MangledName += DVScope.NameSuffix;
7188 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7189
7190 VariantII.setMangledOpenMPVariantName(true);
7191 D.SetIdentifier(&VariantII, D.getBeginLoc());
7192}
7193
7194void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7195 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7196 // Do not mark function as is used to prevent its emission if this is the
7197 // only place where it is used.
7198 EnterExpressionEvaluationContext Unevaluated(
7199 *this, Sema::ExpressionEvaluationContext::Unevaluated);
7200
7201 FunctionDecl *FD = nullptr;
7202 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7203 FD = UTemplDecl->getTemplatedDecl();
7204 else
7205 FD = cast<FunctionDecl>(D);
7206 auto *VariantFuncRef = DeclRefExpr::Create(
7207 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7208 /* RefersToEnclosingVariableOrCapture */ false,
7209 /* NameLoc */ FD->getLocation(), FD->getType(),
7210 ExprValueKind::VK_PRValue);
7211
7212 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7213 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7214 Context, VariantFuncRef, DVScope.TI,
7215 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7216 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7217 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7218 for (FunctionDecl *BaseFD : Bases)
7219 BaseFD->addAttr(OMPDeclareVariantA);
7220}
7221
7222ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7223 SourceLocation LParenLoc,
7224 MultiExprArg ArgExprs,
7225 SourceLocation RParenLoc, Expr *ExecConfig) {
7226 // The common case is a regular call we do not want to specialize at all. Try
7227 // to make that case fast by bailing early.
7228 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7229 if (!CE)
7230 return Call;
7231
7232 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7233 if (!CalleeFnDecl)
7234 return Call;
7235
7236 if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7237 CalleeFnDecl->getName().startswith_insensitive("omp_")) {
7238 // checking for any calls inside an Order region
7239 if (Scope->isOpenMPOrderClauseScope())
7240 Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7241 }
7242
7243 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7244 return Call;
7245
7246 ASTContext &Context = getASTContext();
7247 std::function<void(StringRef)> DiagUnknownTrait = [this,
7248 CE](StringRef ISATrait) {
7249 // TODO Track the selector locations in a way that is accessible here to
7250 // improve the diagnostic location.
7251 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7252 << ISATrait;
7253 };
7254 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7255 getCurFunctionDecl(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructTraits());
7256
7257 QualType CalleeFnType = CalleeFnDecl->getType();
7258
7259 SmallVector<Expr *, 4> Exprs;
7260 SmallVector<VariantMatchInfo, 4> VMIs;
7261 while (CalleeFnDecl) {
7262 for (OMPDeclareVariantAttr *A :
7263 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7264 Expr *VariantRef = A->getVariantFuncRef();
7265
7266 VariantMatchInfo VMI;
7267 OMPTraitInfo &TI = A->getTraitInfo();
7268 TI.getAsVariantMatchInfo(Context, VMI);
7269 if (!isVariantApplicableInContext(VMI, OMPCtx,
7270 /* DeviceSetOnly */ false))
7271 continue;
7272
7273 VMIs.push_back(VMI);
7274 Exprs.push_back(VariantRef);
7275 }
7276
7277 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7278 }
7279
7280 ExprResult NewCall;
7281 do {
7282 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7283 if (BestIdx < 0)
7284 return Call;
7285 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7286 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7287
7288 {
7289 // Try to build a (member) call expression for the current best applicable
7290 // variant expression. We allow this to fail in which case we continue
7291 // with the next best variant expression. The fail case is part of the
7292 // implementation defined behavior in the OpenMP standard when it talks
7293 // about what differences in the function prototypes: "Any differences
7294 // that the specific OpenMP context requires in the prototype of the
7295 // variant from the base function prototype are implementation defined."
7296 // This wording is there to allow the specialized variant to have a
7297 // different type than the base function. This is intended and OK but if
7298 // we cannot create a call the difference is not in the "implementation
7299 // defined range" we allow.
7300 Sema::TentativeAnalysisScope Trap(*this);
7301
7302 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7303 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7304 BestExpr = MemberExpr::CreateImplicit(
7305 Context, MemberCall->getImplicitObjectArgument(),
7306 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7307 MemberCall->getValueKind(), MemberCall->getObjectKind());
7308 }
7309 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7310 ExecConfig);
7311 if (NewCall.isUsable()) {
7312 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7313 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7314 QualType NewType = Context.mergeFunctionTypes(
7315 CalleeFnType, NewCalleeFnDecl->getType(),
7316 /* OfBlockPointer */ false,
7317 /* Unqualified */ false, /* AllowCXX */ true);
7318 if (!NewType.isNull())
7319 break;
7320 // Don't use the call if the function type was not compatible.
7321 NewCall = nullptr;
7322 }
7323 }
7324 }
7325
7326 VMIs.erase(VMIs.begin() + BestIdx);
7327 Exprs.erase(Exprs.begin() + BestIdx);
7328 } while (!VMIs.empty());
7329
7330 if (!NewCall.isUsable())
7331 return Call;
7332 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7333}
7334
7335Optional<std::pair<FunctionDecl *, Expr *>>
7336Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7337 Expr *VariantRef, OMPTraitInfo &TI,
7338 unsigned NumAppendArgs,
7339 SourceRange SR) {
7340 if (!DG || DG.get().isNull())
7341 return std::nullopt;
7342
7343 const int VariantId = 1;
7344 // Must be applied only to single decl.
7345 if (!DG.get().isSingleDecl()) {
7346 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7347 << VariantId << SR;
7348 return std::nullopt;
7349 }
7350 Decl *ADecl = DG.get().getSingleDecl();
7351 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7352 ADecl = FTD->getTemplatedDecl();
7353
7354 // Decl must be a function.
7355 auto *FD = dyn_cast<FunctionDecl>(ADecl);
7356 if (!FD) {
7357 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7358 << VariantId << SR;
7359 return std::nullopt;
7360 }
7361
7362 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7363 // The 'target' attribute needs to be separately checked because it does
7364 // not always signify a multiversion function declaration.
7365 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7366 };
7367 // OpenMP is not compatible with multiversion function attributes.
7368 if (HasMultiVersionAttributes(FD)) {
7369 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7370 << SR;
7371 return std::nullopt;
7372 }
7373
7374 // Allow #pragma omp declare variant only if the function is not used.
7375 if (FD->isUsed(false))
7376 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7377 << FD->getLocation();
7378
7379 // Check if the function was emitted already.
7380 const FunctionDecl *Definition;
7381 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7382 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7383 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7384 << FD->getLocation();
7385
7386 // The VariantRef must point to function.
7387 if (!VariantRef) {
7388 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7389 return std::nullopt;
7390 }
7391
7392 auto ShouldDelayChecks = [](Expr *&E, bool) {
7393 return E && (E->isTypeDependent() || E->isValueDependent() ||
7394 E->containsUnexpandedParameterPack() ||
7395 E->isInstantiationDependent());
7396 };
7397 // Do not check templates, wait until instantiation.
7398 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7399 TI.anyScoreOrCondition(ShouldDelayChecks))
7400 return std::make_pair(FD, VariantRef);
7401
7402 // Deal with non-constant score and user condition expressions.
7403 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7404 bool IsScore) -> bool {
7405 if (!E || E->isIntegerConstantExpr(Context))
7406 return false;
7407
7408 if (IsScore) {
7409 // We warn on non-constant scores and pretend they were not present.
7410 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7411 << E;
7412 E = nullptr;
7413 } else {
7414 // We could replace a non-constant user condition with "false" but we
7415 // will soon need to handle these anyway for the dynamic version of
7416 // OpenMP context selectors.
7417 Diag(E->getExprLoc(),
7418 diag::err_omp_declare_variant_user_condition_not_constant)
7419 << E;
7420 }
7421 return true;
7422 };
7423 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7424 return std::nullopt;
7425
7426 QualType AdjustedFnType = FD->getType();
7427 if (NumAppendArgs) {
7428 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7429 if (!PTy) {
7430 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7431 << SR;
7432 return std::nullopt;
7433 }
7434 // Adjust the function type to account for an extra omp_interop_t for each
7435 // specified in the append_args clause.
7436 const TypeDecl *TD = nullptr;
7437 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7438 SR.getBegin(), Sema::LookupOrdinaryName);
7439 if (LookupName(Result, getCurScope())) {
7440 NamedDecl *ND = Result.getFoundDecl();
7441 TD = dyn_cast_or_null<TypeDecl>(ND);
7442 }
7443 if (!TD) {
7444 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7445 return std::nullopt;
7446 }
7447 QualType InteropType = Context.getTypeDeclType(TD);
7448 if (PTy->isVariadic()) {
7449 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7450 return std::nullopt;
7451 }
7452 llvm::SmallVector<QualType, 8> Params;
7453 Params.append(PTy->param_type_begin(), PTy->param_type_end());
7454 Params.insert(Params.end(), NumAppendArgs, InteropType);
7455 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7456 PTy->getExtProtoInfo());
7457 }
7458
7459 // Convert VariantRef expression to the type of the original function to
7460 // resolve possible conflicts.
7461 ExprResult VariantRefCast = VariantRef;
7462 if (LangOpts.CPlusPlus) {
7463 QualType FnPtrType;
7464 auto *Method = dyn_cast<CXXMethodDecl>(FD);
7465 if (Method && !Method->isStatic()) {
7466 const Type *ClassType =
7467 Context.getTypeDeclType(Method->getParent()).getTypePtr();
7468 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7469 ExprResult ER;
7470 {
7471 // Build adrr_of unary op to correctly handle type checks for member
7472 // functions.
7473 Sema::TentativeAnalysisScope Trap(*this);
7474 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7475 VariantRef);
7476 }
7477 if (!ER.isUsable()) {
7478 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7479 << VariantId << VariantRef->getSourceRange();
7480 return std::nullopt;
7481 }
7482 VariantRef = ER.get();
7483 } else {
7484 FnPtrType = Context.getPointerType(AdjustedFnType);
7485 }
7486 QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7487 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7488 ImplicitConversionSequence ICS = TryImplicitConversion(
7489 VariantRef, FnPtrType.getUnqualifiedType(),
7490 /*SuppressUserConversions=*/false, AllowedExplicit::None,
7491 /*InOverloadResolution=*/false,
7492 /*CStyle=*/false,
7493 /*AllowObjCWritebackConversion=*/false);
7494 if (ICS.isFailure()) {
7495 Diag(VariantRef->getExprLoc(),
7496 diag::err_omp_declare_variant_incompat_types)
7497 << VariantRef->getType()
7498 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7499 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7500 return std::nullopt;
7501 }
7502 VariantRefCast = PerformImplicitConversion(
7503 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7504 if (!VariantRefCast.isUsable())
7505 return std::nullopt;
7506 }
7507 // Drop previously built artificial addr_of unary op for member functions.
7508 if (Method && !Method->isStatic()) {
7509 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7510 if (auto *UO = dyn_cast<UnaryOperator>(
7511 PossibleAddrOfVariantRef->IgnoreImplicit()))
7512 VariantRefCast = UO->getSubExpr();
7513 }
7514 }
7515
7516 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7517 if (!ER.isUsable() ||
7518 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7519 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7520 << VariantId << VariantRef->getSourceRange();
7521 return std::nullopt;
7522 }
7523
7524 // The VariantRef must point to function.
7525 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7526 if (!DRE) {
7527 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7528 << VariantId << VariantRef->getSourceRange();
7529 return std::nullopt;
7530 }
7531 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7532 if (!NewFD) {
7533 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7534 << VariantId << VariantRef->getSourceRange();
7535 return std::nullopt;
7536 }
7537
7538 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7539 Diag(VariantRef->getExprLoc(),
7540 diag::err_omp_declare_variant_same_base_function)
7541 << VariantRef->getSourceRange();
7542 return std::nullopt;
7543 }
7544
7545 // Check if function types are compatible in C.
7546 if (!LangOpts.CPlusPlus) {
7547 QualType NewType =
7548 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7549 if (NewType.isNull()) {
7550 Diag(VariantRef->getExprLoc(),
7551 diag::err_omp_declare_variant_incompat_types)
7552 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7553 << VariantRef->getSourceRange();
7554 return std::nullopt;
7555 }
7556 if (NewType->isFunctionProtoType()) {
7557 if (FD->getType()->isFunctionNoProtoType())
7558 setPrototype(*this, FD, NewFD, NewType);
7559 else if (NewFD->getType()->isFunctionNoProtoType())
7560 setPrototype(*this, NewFD, FD, NewType);
7561 }
7562 }
7563
7564 // Check if variant function is not marked with declare variant directive.
7565 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7566 Diag(VariantRef->getExprLoc(),
7567 diag::warn_omp_declare_variant_marked_as_declare_variant)
7568 << VariantRef->getSourceRange();
7569 SourceRange SR =
7570 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7571 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7572 return std::nullopt;
7573 }
7574
7575 enum DoesntSupport {
7576 VirtFuncs = 1,
7577 Constructors = 3,
7578 Destructors = 4,
7579 DeletedFuncs = 5,
7580 DefaultedFuncs = 6,
7581 ConstexprFuncs = 7,
7582 ConstevalFuncs = 8,
7583 };
7584 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7585 if (CXXFD->isVirtual()) {
7586 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7587 << VirtFuncs;
7588 return std::nullopt;
7589 }
7590
7591 if (isa<CXXConstructorDecl>(FD)) {
7592 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7593 << Constructors;
7594 return std::nullopt;
7595 }
7596
7597 if (isa<CXXDestructorDecl>(FD)) {
7598 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7599 << Destructors;
7600 return std::nullopt;
7601 }
7602 }
7603
7604 if (FD->isDeleted()) {
7605 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7606 << DeletedFuncs;
7607 return std::nullopt;
7608 }
7609
7610 if (FD->isDefaulted()) {
7611 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7612 << DefaultedFuncs;
7613 return std::nullopt;
7614 }
7615
7616 if (FD->isConstexpr()) {
7617 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7618 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7619 return std::nullopt;
7620 }
7621
7622 // Check general compatibility.
7623 if (areMultiversionVariantFunctionsCompatible(
7624 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7625 PartialDiagnosticAt(SourceLocation(),
7626 PartialDiagnostic::NullDiagnostic()),
7627 PartialDiagnosticAt(
7628 VariantRef->getExprLoc(),
7629 PDiag(diag::err_omp_declare_variant_doesnt_support)),
7630 PartialDiagnosticAt(VariantRef->getExprLoc(),
7631 PDiag(diag::err_omp_declare_variant_diff)
7632 << FD->getLocation()),
7633 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7634 /*CLinkageMayDiffer=*/true))
7635 return std::nullopt;
7636 return std::make_pair(FD, cast<Expr>(DRE));
7637}
7638
7639void Sema::ActOnOpenMPDeclareVariantDirective(
7640 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7641 ArrayRef<Expr *> AdjustArgsNothing,
7642 ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7643 ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7644 SourceLocation AppendArgsLoc, SourceRange SR) {
7645
7646 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7647 // An adjust_args clause or append_args clause can only be specified if the
7648 // dispatch selector of the construct selector set appears in the match
7649 // clause.
7650
7651 SmallVector<Expr *, 8> AllAdjustArgs;
7652 llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7653 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7654
7655 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7656 VariantMatchInfo VMI;
7657 TI.getAsVariantMatchInfo(Context, VMI);
7658 if (!llvm::is_contained(
7659 VMI.ConstructTraits,
7660 llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7661 if (!AllAdjustArgs.empty())
7662 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7663 << getOpenMPClauseName(OMPC_adjust_args);
7664 if (!AppendArgs.empty())
7665 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7666 << getOpenMPClauseName(OMPC_append_args);
7667 return;
7668 }
7669 }
7670
7671 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7672 // Each argument can only appear in a single adjust_args clause for each
7673 // declare variant directive.
7674 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7675
7676 for (Expr *E : AllAdjustArgs) {
7677 E = E->IgnoreParenImpCasts();
7678 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7679 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7680 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7681 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7682 FD->getParamDecl(PVD->getFunctionScopeIndex())
7683 ->getCanonicalDecl() == CanonPVD) {
7684 // It's a parameter of the function, check duplicates.
7685 if (!AdjustVars.insert(CanonPVD).second) {
7686 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7687 << PVD;
7688 return;
7689 }
7690 continue;
7691 }
7692 }
7693 }
7694 // Anything that is not a function parameter is an error.
7695 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7696 return;
7697 }
7698
7699 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7700 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7701 AdjustArgsNothing.size(),
7702 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7703 AdjustArgsNeedDevicePtr.size(),
7704 const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7705 FD->addAttr(NewAttr);
7706}
7707
7708StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7709 Stmt *AStmt,
7710 SourceLocation StartLoc,
7711 SourceLocation EndLoc) {
7712 if (!AStmt)
7713 return StmtError();
7714
7715 auto *CS = cast<CapturedStmt>(AStmt);
7716 // 1.2.2 OpenMP Language Terminology
7717 // Structured block - An executable statement with a single entry at the
7718 // top and a single exit at the bottom.
7719 // The point of exit cannot be a branch out of the structured block.
7720 // longjmp() and throw() must not violate the entry/exit criteria.
7721 CS->getCapturedDecl()->setNothrow();
7722
7723 setFunctionHasBranchProtectedScope();
7724
7725 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7726 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
7727 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7728}
7729
7730namespace {
7731/// Iteration space of a single for loop.
7732struct LoopIterationSpace final {
7733 /// True if the condition operator is the strict compare operator (<, > or
7734 /// !=).
7735 bool IsStrictCompare = false;
7736 /// Condition of the loop.
7737 Expr *PreCond = nullptr;
7738 /// This expression calculates the number of iterations in the loop.
7739 /// It is always possible to calculate it before starting the loop.
7740 Expr *NumIterations = nullptr;
7741 /// The loop counter variable.
7742 Expr *CounterVar = nullptr;
7743 /// Private loop counter variable.
7744 Expr *PrivateCounterVar = nullptr;
7745 /// This is initializer for the initial value of #CounterVar.
7746 Expr *CounterInit = nullptr;
7747 /// This is step for the #CounterVar used to generate its update:
7748 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7749 Expr *CounterStep = nullptr;
7750 /// Should step be subtracted?
7751 bool Subtract = false;
7752 /// Source range of the loop init.
7753 SourceRange InitSrcRange;
7754 /// Source range of the loop condition.
7755 SourceRange CondSrcRange;
7756 /// Source range of the loop increment.
7757 SourceRange IncSrcRange;
7758 /// Minimum value that can have the loop control variable. Used to support
7759 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7760 /// since only such variables can be used in non-loop invariant expressions.
7761 Expr *MinValue = nullptr;
7762 /// Maximum value that can have the loop control variable. Used to support
7763 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7764 /// since only such variables can be used in non-loop invariant expressions.
7765 Expr *MaxValue = nullptr;
7766 /// true, if the lower bound depends on the outer loop control var.
7767 bool IsNonRectangularLB = false;
7768 /// true, if the upper bound depends on the outer loop control var.
7769 bool IsNonRectangularUB = false;
7770 /// Index of the loop this loop depends on and forms non-rectangular loop
7771 /// nest.
7772 unsigned LoopDependentIdx = 0;
7773 /// Final condition for the non-rectangular loop nest support. It is used to
7774 /// check that the number of iterations for this particular counter must be
7775 /// finished.
7776 Expr *FinalCondition = nullptr;
7777};
7778
7779/// Helper class for checking canonical form of the OpenMP loops and
7780/// extracting iteration space of each loop in the loop nest, that will be used
7781/// for IR generation.
7782class OpenMPIterationSpaceChecker {
7783 /// Reference to Sema.
7784 Sema &SemaRef;
7785 /// Does the loop associated directive support non-rectangular loops?
7786 bool SupportsNonRectangular;
7787 /// Data-sharing stack.
7788 DSAStackTy &Stack;
7789 /// A location for diagnostics (when there is no some better location).
7790 SourceLocation DefaultLoc;
7791 /// A location for diagnostics (when increment is not compatible).
7792 SourceLocation ConditionLoc;
7793 /// A source location for referring to loop init later.
7794 SourceRange InitSrcRange;
7795 /// A source location for referring to condition later.
7796 SourceRange ConditionSrcRange;
7797 /// A source location for referring to increment later.
7798 SourceRange IncrementSrcRange;
7799 /// Loop variable.
7800 ValueDecl *LCDecl = nullptr;
7801 /// Reference to loop variable.
7802 Expr *LCRef = nullptr;
7803 /// Lower bound (initializer for the var).
7804 Expr *LB = nullptr;
11
Null pointer value stored to 'ISC.LB'
7805 /// Upper bound.
7806 Expr *UB = nullptr;
7807 /// Loop step (increment).
7808 Expr *Step = nullptr;
7809 /// This flag is true when condition is one of:
7810 /// Var < UB
7811 /// Var <= UB
7812 /// UB > Var
7813 /// UB >= Var
7814 /// This will have no value when the condition is !=
7815 llvm::Optional<bool> TestIsLessOp;
7816 /// This flag is true when condition is strict ( < or > ).
7817 bool TestIsStrictOp = false;
7818 /// This flag is true when step is subtracted on each iteration.
7819 bool SubtractStep = false;
7820 /// The outer loop counter this loop depends on (if any).
7821 const ValueDecl *DepDecl = nullptr;
7822 /// Contains number of loop (starts from 1) on which loop counter init
7823 /// expression of this loop depends on.
7824 Optional<unsigned> InitDependOnLC;
7825 /// Contains number of loop (starts from 1) on which loop counter condition
7826 /// expression of this loop depends on.
7827 Optional<unsigned> CondDependOnLC;
7828 /// Checks if the provide statement depends on the loop counter.
7829 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7830 /// Original condition required for checking of the exit condition for
7831 /// non-rectangular loop.
7832 Expr *Condition = nullptr;
7833
7834public:
7835 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7836 DSAStackTy &Stack, SourceLocation DefaultLoc)
7837 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7838 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7839 /// Check init-expr for canonical loop form and save loop counter
7840 /// variable - #Var and its initialization value - #LB.
7841 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7842 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7843 /// for less/greater and for strict/non-strict comparison.
7844 bool checkAndSetCond(Expr *S);
7845 /// Check incr-expr for canonical loop form and return true if it
7846 /// does not conform, otherwise save loop step (#Step).
7847 bool checkAndSetInc(Expr *S);
7848 /// Return the loop counter variable.
7849 ValueDecl *getLoopDecl() const { return LCDecl; }
7850 /// Return the reference expression to loop counter variable.
7851 Expr *getLoopDeclRefExpr() const { return LCRef; }
7852 /// Source range of the loop init.
7853 SourceRange getInitSrcRange() const { return InitSrcRange; }
7854 /// Source range of the loop condition.
7855 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7856 /// Source range of the loop increment.
7857 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7858 /// True if the step should be subtracted.
7859 bool shouldSubtractStep() const { return SubtractStep; }
7860 /// True, if the compare operator is strict (<, > or !=).
7861 bool isStrictTestOp() const { return TestIsStrictOp; }
7862 /// Build the expression to calculate the number of iterations.
7863 Expr *buildNumIterations(
7864 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7865 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7866 /// Build the precondition expression for the loops.
7867 Expr *
7868 buildPreCond(Scope *S, Expr *Cond,
7869 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7870 /// Build reference expression to the counter be used for codegen.
7871 DeclRefExpr *
7872 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7873 DSAStackTy &DSA) const;
7874 /// Build reference expression to the private counter be used for
7875 /// codegen.
7876 Expr *buildPrivateCounterVar() const;
7877 /// Build initialization of the counter be used for codegen.
7878 Expr *buildCounterInit() const;
7879 /// Build step of the counter be used for codegen.
7880 Expr *buildCounterStep() const;
7881 /// Build loop data with counter value for depend clauses in ordered
7882 /// directives.
7883 Expr *
7884 buildOrderedLoopData(Scope *S, Expr *Counter,
7885 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7886 SourceLocation Loc, Expr *Inc = nullptr,
7887 OverloadedOperatorKind OOK = OO_Amp);
7888 /// Builds the minimum value for the loop counter.
7889 std::pair<Expr *, Expr *> buildMinMaxValues(
7890 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7891 /// Builds final condition for the non-rectangular loops.
7892 Expr *buildFinalCondition(Scope *S) const;
7893 /// Return true if any expression is dependent.
7894 bool dependent() const;
7895 /// Returns true if the initializer forms non-rectangular loop.
7896 bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
7897 /// Returns true if the condition forms non-rectangular loop.
7898 bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
7899 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7900 unsigned getLoopDependentIdx() const {
7901 return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7902 }
7903
7904private:
7905 /// Check the right-hand side of an assignment in the increment
7906 /// expression.
7907 bool checkAndSetIncRHS(Expr *RHS);
7908 /// Helper to set loop counter variable and its initializer.
7909 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7910 bool EmitDiags);
7911 /// Helper to set upper bound.
7912 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7913 SourceRange SR, SourceLocation SL);
7914 /// Helper to set loop increment.
7915 bool setStep(Expr *NewStep, bool Subtract);
7916};
7917
7918bool OpenMPIterationSpaceChecker::dependent() const {
7919 if (!LCDecl) {
7920 assert(!LB && !UB && !Step)(static_cast <bool> (!LB && !UB && !Step
) ? void (0) : __assert_fail ("!LB && !UB && !Step"
, "clang/lib/Sema/SemaOpenMP.cpp", 7920, __extension__ __PRETTY_FUNCTION__
))
;
7921 return false;
7922 }
7923 return LCDecl->getType()->isDependentType() ||
7924 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7925 (Step && Step->isValueDependent());
7926}
7927
7928bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7929 Expr *NewLCRefExpr,
7930 Expr *NewLB, bool EmitDiags) {
7931 // State consistency checking to ensure correct usage.
7932 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", 7933, __extension__ __PRETTY_FUNCTION__
))
7933 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", 7933, __extension__ __PRETTY_FUNCTION__
))
;
7934 if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7935 return true;
7936 LCDecl = getCanonicalDecl(NewLCDecl);
7937 LCRef = NewLCRefExpr;
7938 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7939 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7940 if ((Ctor->isCopyOrMoveConstructor() ||
7941 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7942 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7943 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7944 LB = NewLB;
7945 if (EmitDiags)
7946 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7947 return false;
7948}
7949
7950bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7951 llvm::Optional<bool> LessOp,
7952 bool StrictOp, SourceRange SR,
7953 SourceLocation SL) {
7954 // State consistency checking to ensure correct usage.
7955 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", 7956, __extension__ __PRETTY_FUNCTION__
))
7956 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", 7956, __extension__ __PRETTY_FUNCTION__
))
;
7957 if (!NewUB || NewUB->containsErrors())
7958 return true;
7959 UB = NewUB;
7960 if (LessOp)
7961 TestIsLessOp = LessOp;
7962 TestIsStrictOp = StrictOp;
7963 ConditionSrcRange = SR;
7964 ConditionLoc = SL;
7965 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7966 return false;
7967}
7968
7969bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7970 // State consistency checking to ensure correct usage.
7971 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", 7971, __extension__ __PRETTY_FUNCTION__
))
;
7972 if (!NewStep || NewStep->containsErrors())
7973 return true;
7974 if (!NewStep->isValueDependent()) {
7975 // Check that the step is integer expression.
7976 SourceLocation StepLoc = NewStep->getBeginLoc();
7977 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7978 StepLoc, getExprAsWritten(NewStep));
7979 if (Val.isInvalid())
7980 return true;
7981 NewStep = Val.get();
7982
7983 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7984 // If test-expr is of form var relational-op b and relational-op is < or
7985 // <= then incr-expr must cause var to increase on each iteration of the
7986 // loop. If test-expr is of form var relational-op b and relational-op is
7987 // > or >= then incr-expr must cause var to decrease on each iteration of
7988 // the loop.
7989 // If test-expr is of form b relational-op var and relational-op is < or
7990 // <= then incr-expr must cause var to decrease on each iteration of the
7991 // loop. If test-expr is of form b relational-op var and relational-op is
7992 // > or >= then incr-expr must cause var to increase on each iteration of
7993 // the loop.
7994 Optional<llvm::APSInt> Result =
7995 NewStep->getIntegerConstantExpr(SemaRef.Context);
7996 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7997 bool IsConstNeg =
7998 Result && Result->isSigned() && (Subtract != Result->isNegative());
7999 bool IsConstPos =
8000 Result && Result->isSigned() && (Subtract == Result->isNegative());
8001 bool IsConstZero = Result && !Result->getBoolValue();
8002
8003 // != with increment is treated as <; != with decrement is treated as >
8004 if (!TestIsLessOp)
8005 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8006 if (UB && (IsConstZero ||
8007 (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8008 : (IsConstPos || (IsUnsigned && !Subtract))))) {
8009 SemaRef.Diag(NewStep->getExprLoc(),
8010 diag::err_omp_loop_incr_not_compatible)
8011 << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8012 SemaRef.Diag(ConditionLoc,
8013 diag::note_omp_loop_cond_requres_compatible_incr)
8014 << *TestIsLessOp << ConditionSrcRange;
8015 return true;
8016 }
8017 if (*TestIsLessOp == Subtract) {
8018 NewStep =
8019 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8020 .get();
8021 Subtract = !Subtract;
8022 }
8023 }
8024
8025 Step = NewStep;
8026 SubtractStep = Subtract;
8027 return false;
8028}
8029
8030namespace {
8031/// Checker for the non-rectangular loops. Checks if the initializer or
8032/// condition expression references loop counter variable.
8033class LoopCounterRefChecker final
8034 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8035 Sema &SemaRef;
8036 DSAStackTy &Stack;
8037 const ValueDecl *CurLCDecl = nullptr;
8038 const ValueDecl *DepDecl = nullptr;
8039 const ValueDecl *PrevDepDecl = nullptr;
8040 bool IsInitializer = true;
8041 bool SupportsNonRectangular;
8042 unsigned BaseLoopId = 0;
8043 bool checkDecl(const Expr *E, const ValueDecl *VD) {
8044 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8045 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8046 << (IsInitializer ? 0 : 1);
8047 return false;
8048 }
8049 const auto &&Data = Stack.isLoopControlVariable(VD);
8050 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8051 // The type of the loop iterator on which we depend may not have a random
8052 // access iterator type.
8053 if (Data.first && VD->getType()->isRecordType()) {
8054 SmallString<128> Name;
8055 llvm::raw_svector_ostream OS(Name);
8056 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8057 /*Qualified=*/true);
8058 SemaRef.Diag(E->getExprLoc(),
8059 diag::err_omp_wrong_dependency_iterator_type)
8060 << OS.str();
8061 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8062 return false;
8063 }
8064 if (Data.first && !SupportsNonRectangular) {
8065 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8066 return false;
8067 }
8068 if (Data.first &&
8069 (DepDecl || (PrevDepDecl &&
8070 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8071 if (!DepDecl && PrevDepDecl)
8072 DepDecl = PrevDepDecl;
8073 SmallString<128> Name;
8074 llvm::raw_svector_ostream OS(Name);
8075 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8076 /*Qualified=*/true);
8077 SemaRef.Diag(E->getExprLoc(),
8078 diag::err_omp_invariant_or_linear_dependency)
8079 << OS.str();
8080 return false;
8081 }
8082 if (Data.first) {
8083 DepDecl = VD;
8084 BaseLoopId = Data.first;
8085 }
8086 return Data.first;
8087 }
8088
8089public:
8090 bool VisitDeclRefExpr(const DeclRefExpr *E) {
8091 const ValueDecl *VD = E->getDecl();
8092 if (isa<VarDecl>(VD))
8093 return checkDecl(E, VD);
8094 return false;
8095 }
8096 bool VisitMemberExpr(const MemberExpr *E) {
8097 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8098 const ValueDecl *VD = E->getMemberDecl();
8099 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8100 return checkDecl(E, VD);
8101 }
8102 return false;
8103 }
8104 bool VisitStmt(const Stmt *S) {
8105 bool Res = false;
8106 for (const Stmt *Child : S->children())
8107 Res = (Child && Visit(Child)) || Res;
8108 return Res;
8109 }
8110 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8111 const ValueDecl *CurLCDecl, bool IsInitializer,
8112 const ValueDecl *PrevDepDecl = nullptr,
8113 bool SupportsNonRectangular = true)
8114 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8115 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8116 SupportsNonRectangular(SupportsNonRectangular) {}
8117 unsigned getBaseLoopId() const {
8118 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", 8118, __extension__ __PRETTY_FUNCTION__
))
;
8119 return BaseLoopId;
8120 }
8121 const ValueDecl *getDepDecl() const {
8122 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", 8122, __extension__ __PRETTY_FUNCTION__
))
;
8123 return DepDecl;
8124 }
8125};
8126} // namespace
8127
8128Optional<unsigned>
8129OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8130 bool IsInitializer) {
8131 // Check for the non-rectangular loops.
8132 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8133 DepDecl, SupportsNonRectangular);
8134 if (LoopStmtChecker.Visit(S)) {
8135 DepDecl = LoopStmtChecker.getDepDecl();
8136 return LoopStmtChecker.getBaseLoopId();
8137 }
8138 return std::nullopt;
8139}
8140
8141bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8142 // Check init-expr for canonical loop form and save loop counter
8143 // variable - #Var and its initialization value - #LB.
8144 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8145 // var = lb
8146 // integer-type var = lb
8147 // random-access-iterator-type var = lb
8148 // pointer-type var = lb
8149 //
8150 if (!S) {
8151 if (EmitDiags) {
8152 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8153 }
8154 return true;
8155 }
8156 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8157 if (!ExprTemp->cleanupsHaveSideEffects())
8158 S = ExprTemp->getSubExpr();
8159
8160 InitSrcRange = S->getSourceRange();
8161 if (Expr *E = dyn_cast<Expr>(S))
8162 S = E->IgnoreParens();
8163 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8164 if (BO->getOpcode() == BO_Assign) {
8165 Expr *LHS = BO->getLHS()->IgnoreParens();
8166 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8167 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8168 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8169 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8170 EmitDiags);
8171 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8172 }
8173 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8174 if (ME->isArrow() &&
8175 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8176 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8177 EmitDiags);
8178 }
8179 }
8180 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8181 if (DS->isSingleDecl()) {
8182 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8183 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8184 // Accept non-canonical init form here but emit ext. warning.
8185 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8186 SemaRef.Diag(S->getBeginLoc(),
8187 diag::ext_omp_loop_not_canonical_init)
8188 << S->getSourceRange();
8189 return setLCDeclAndLB(
8190 Var,
8191 buildDeclRefExpr(SemaRef, Var,
8192 Var->getType().getNonReferenceType(),
8193 DS->getBeginLoc()),
8194 Var->getInit(), EmitDiags);
8195 }
8196 }
8197 }
8198 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8199 if (CE->getOperator() == OO_Equal) {
8200 Expr *LHS = CE->getArg(0);
8201 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8202 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8203 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8204 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8205 EmitDiags);
8206 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8207 }
8208 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8209 if (ME->isArrow() &&
8210 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8211 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8212 EmitDiags);
8213 }
8214 }
8215 }
8216
8217 if (dependent() || SemaRef.CurContext->isDependentContext())
8218 return false;
8219 if (EmitDiags) {
8220 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8221 << S->getSourceRange();
8222 }
8223 return true;
8224}
8225
8226/// Ignore parenthesizes, implicit casts, copy constructor and return the
8227/// variable (which may be the loop variable) if possible.
8228static const ValueDecl *getInitLCDecl(const Expr *E) {
8229 if (!E)
8230 return nullptr;
8231 E = getExprAsWritten(E);
8232 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8233 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8234 if ((Ctor->isCopyOrMoveConstructor() ||
8235 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8236 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8237 E = CE->getArg(0)->IgnoreParenImpCasts();
8238 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8239 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8240 return getCanonicalDecl(VD);
8241 }
8242 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8243 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8244 return getCanonicalDecl(ME->getMemberDecl());
8245 return nullptr;
8246}
8247
8248bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8249 // Check test-expr for canonical form, save upper-bound UB, flags for
8250 // less/greater and for strict/non-strict comparison.
8251 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8252 // var relational-op b
8253 // b relational-op var
8254 //
8255 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8256 if (!S) {
8257 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8258 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8259 return true;
8260 }
8261 Condition = S;
8262 S = getExprAsWritten(S);
8263 SourceLocation CondLoc = S->getBeginLoc();
8264 auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
8265 BinaryOperatorKind Opcode, const Expr *LHS,
8266 const Expr *RHS, SourceRange SR,
8267 SourceLocation OpLoc) -> llvm::Optional<bool> {
8268 if (BinaryOperator::isRelationalOp(Opcode)) {
8269 if (getInitLCDecl(LHS) == LCDecl)
8270 return setUB(const_cast<Expr *>(RHS),
8271 (Opcode == BO_LT || Opcode == BO_LE),
8272 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8273 if (getInitLCDecl(RHS) == LCDecl)
8274 return setUB(const_cast<Expr *>(LHS),
8275 (Opcode == BO_GT || Opcode == BO_GE),
8276 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8277 } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8278 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8279 /*LessOp=*/std::nullopt,
8280 /*StrictOp=*/true, SR, OpLoc);
8281 }
8282 return std::nullopt;
8283 };
8284 llvm::Optional<bool> Res;
8285 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8286 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8287 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8288 RBO->getOperatorLoc());
8289 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8290 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8291 BO->getSourceRange(), BO->getOperatorLoc());
8292 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8293 if (CE->getNumArgs() == 2) {
8294 Res = CheckAndSetCond(
8295 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8296 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8297 }
8298 }
8299 if (Res)
8300 return *Res;
8301 if (dependent() || SemaRef.CurContext->isDependentContext())
8302 return false;
8303 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8304 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8305 return true;
8306}
8307
8308bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8309 // RHS of canonical loop form increment can be:
8310 // var + incr
8311 // incr + var
8312 // var - incr
8313 //
8314 RHS = RHS->IgnoreParenImpCasts();
8315 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8316 if (BO->isAdditiveOp()) {
8317 bool IsAdd = BO->getOpcode() == BO_Add;
8318 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8319 return setStep(BO->getRHS(), !IsAdd);
8320 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8321 return setStep(BO->getLHS(), /*Subtract=*/false);
8322 }
8323 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8324 bool IsAdd = CE->getOperator() == OO_Plus;
8325 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8326 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8327 return setStep(CE->getArg(1), !IsAdd);
8328 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8329 return setStep(CE->getArg(0), /*Subtract=*/false);
8330 }
8331 }
8332 if (dependent() || SemaRef.CurContext->isDependentContext())
8333 return false;
8334 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8335 << RHS->getSourceRange() << LCDecl;
8336 return true;
8337}
8338
8339bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8340 // Check incr-expr for canonical loop form and return true if it
8341 // does not conform.
8342 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8343 // ++var
8344 // var++
8345 // --var
8346 // var--
8347 // var += incr
8348 // var -= incr
8349 // var = var + incr
8350 // var = incr + var
8351 // var = var - incr
8352 //
8353 if (!S) {
8354 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8355 return true;
8356 }
8357 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8358 if (!ExprTemp->cleanupsHaveSideEffects())
8359 S = ExprTemp->getSubExpr();
8360
8361 IncrementSrcRange = S->getSourceRange();
8362 S = S->IgnoreParens();
8363 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8364 if (UO->isIncrementDecrementOp() &&
8365 getInitLCDecl(UO->getSubExpr()) == LCDecl)
8366 return setStep(SemaRef
8367 .ActOnIntegerConstant(UO->getBeginLoc(),
8368 (UO->isDecrementOp() ? -1 : 1))
8369 .get(),
8370 /*Subtract=*/false);
8371 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8372 switch (BO->getOpcode()) {
8373 case BO_AddAssign:
8374 case BO_SubAssign:
8375 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8376 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8377 break;
8378 case BO_Assign:
8379 if (getInitLCDecl(BO->getLHS()) == LCDecl)
8380 return checkAndSetIncRHS(BO->getRHS());
8381 break;
8382 default:
8383 break;
8384 }
8385 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8386 switch (CE->getOperator()) {
8387 case OO_PlusPlus:
8388 case OO_MinusMinus:
8389 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8390 return setStep(SemaRef
8391 .ActOnIntegerConstant(
8392 CE->getBeginLoc(),
8393 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8394 .get(),
8395 /*Subtract=*/false);
8396 break;
8397 case OO_PlusEqual:
8398 case OO_MinusEqual:
8399 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8400 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8401 break;
8402 case OO_Equal:
8403 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8404 return checkAndSetIncRHS(CE->getArg(1));
8405 break;
8406 default:
8407 break;
8408 }
8409 }
8410 if (dependent() || SemaRef.CurContext->isDependentContext())
8411 return false;
8412 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8413 << S->getSourceRange() << LCDecl;
8414 return true;
8415}
8416
8417static ExprResult
8418tryBuildCapture(Sema &SemaRef, Expr *Capture,
8419 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8420 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
22
Assuming the condition is false
23
Called C++ object pointer is null
8421 return Capture;
8422 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8423 return SemaRef.PerformImplicitConversion(
8424 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8425 /*AllowExplicit=*/true);
8426 auto I = Captures.find(Capture);
8427 if (I != Captures.end())
8428 return buildCapture(SemaRef, Capture, I->second);
8429 DeclRefExpr *Ref = nullptr;
8430 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
8431 Captures[Capture] = Ref;
8432 return Res;
8433}
8434
8435/// Calculate number of iterations, transforming to unsigned, if number of
8436/// iterations may be larger than the original type.
8437static Expr *
8438calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8439 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8440 bool TestIsStrictOp, bool RoundToStep,
8441 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8442 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8443 if (!NewStep.isUsable())
8444 return nullptr;
8445 llvm::APSInt LRes, SRes;
8446 bool IsLowerConst = false, IsStepConst = false;
8447 if (Optional<llvm::APSInt> Res =
8448 Lower->getIntegerConstantExpr(SemaRef.Context)) {
8449 LRes = *Res;
8450 IsLowerConst = true;
8451 }
8452 if (Optional<llvm::APSInt> Res =
8453 Step->getIntegerConstantExpr(SemaRef.Context)) {
8454 SRes = *Res;
8455 IsStepConst = true;
8456 }
8457 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8458 ((!TestIsStrictOp && LRes.isNonNegative()) ||
8459 (TestIsStrictOp && LRes.isStrictlyPositive()));
8460 bool NeedToReorganize = false;
8461 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8462 if (!NoNeedToConvert && IsLowerConst &&
8463 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8464 NoNeedToConvert = true;
8465 if (RoundToStep) {
8466 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8467 ? LRes.getBitWidth()
8468 : SRes.getBitWidth();
8469 LRes = LRes.extend(BW + 1);
8470 LRes.setIsSigned(true);
8471 SRes = SRes.extend(BW + 1);
8472 SRes.setIsSigned(true);
8473 LRes -= SRes;
8474 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8475 LRes = LRes.trunc(BW);
8476 }
8477 if (TestIsStrictOp) {
8478 unsigned BW = LRes.getBitWidth();
8479 LRes = LRes.extend(BW + 1);
8480 LRes.setIsSigned(true);
8481 ++LRes;
8482 NoNeedToConvert =
8483 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8484 // truncate to the original bitwidth.
8485 LRes = LRes.trunc(BW);
8486 }
8487 NeedToReorganize = NoNeedToConvert;
8488 }
8489 llvm::APSInt URes;
8490 bool IsUpperConst = false;
8491 if (Optional<llvm::APSInt> Res =
8492 Upper->getIntegerConstantExpr(SemaRef.Context)) {
8493 URes = *Res;
8494 IsUpperConst = true;
8495 }
8496 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8497 (!RoundToStep || IsStepConst)) {
8498 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8499 : URes.getBitWidth();
8500 LRes = LRes.extend(BW + 1);
8501 LRes.setIsSigned(true);
8502 URes = URes.extend(BW + 1);
8503 URes.setIsSigned(true);
8504 URes -= LRes;
8505 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8506 NeedToReorganize = NoNeedToConvert;
8507 }
8508 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8509 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8510 // unsigned.
8511 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8512 !LCTy->isDependentType() && LCTy->isIntegerType()) {
8513 QualType LowerTy = Lower->getType();
8514 QualType UpperTy = Upper->getType();
8515 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8516 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8517 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8518 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8519 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8520 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8521 Upper =
8522 SemaRef
8523 .PerformImplicitConversion(
8524 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8525 CastType, Sema::AA_Converting)
8526 .get();
8527 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8528 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8529 }
8530 }
8531 if (!Lower || !Upper || NewStep.isInvalid())
8532 return nullptr;
8533
8534 ExprResult Diff;
8535 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8536 // 1]).
8537 if (NeedToReorganize) {
8538 Diff = Lower;
8539
8540 if (RoundToStep) {
8541 // Lower - Step
8542 Diff =
8543 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8544 if (!Diff.isUsable())
8545 return nullptr;
8546 }
8547
8548 // Lower - Step [+ 1]
8549 if (TestIsStrictOp)
8550 Diff = SemaRef.BuildBinOp(
8551 S, DefaultLoc, BO_Add, Diff.get(),
8552 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8553 if (!Diff.isUsable())
8554 return nullptr;
8555
8556 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8557 if (!Diff.isUsable())
8558 return nullptr;
8559
8560 // Upper - (Lower - Step [+ 1]).
8561 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8562 if (!Diff.isUsable())
8563 return nullptr;
8564 } else {
8565 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8566
8567 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8568 // BuildBinOp already emitted error, this one is to point user to upper
8569 // and lower bound, and to tell what is passed to 'operator-'.
8570 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8571 << Upper->getSourceRange() << Lower->getSourceRange();
8572 return nullptr;
8573 }
8574
8575 if (!Diff.isUsable())
8576 return nullptr;
8577
8578 // Upper - Lower [- 1]
8579 if (TestIsStrictOp)
8580 Diff = SemaRef.BuildBinOp(
8581 S, DefaultLoc, BO_Sub, Diff.get(),
8582 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8583 if (!Diff.isUsable())
8584 return nullptr;
8585
8586 if (RoundToStep) {
8587 // Upper - Lower [- 1] + Step
8588 Diff =
8589 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8590 if (!Diff.isUsable())
8591 return nullptr;
8592 }
8593 }
8594
8595 // Parentheses (for dumping/debugging purposes only).
8596 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8597 if (!Diff.isUsable())
8598 return nullptr;
8599
8600 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8601 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8602 if (!Diff.isUsable())
8603 return nullptr;
8604
8605 return Diff.get();
8606}
8607
8608/// Build the expression to calculate the number of iterations.
8609Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8610 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8611 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8612 QualType VarType = LCDecl->getType().getNonReferenceType();
8613 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8614 !SemaRef.getLangOpts().CPlusPlus)
8615 return nullptr;
8616 Expr *LBVal = LB;
8617 Expr *UBVal = UB;
8618 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8619 // max(LB(MinVal), LB(MaxVal))
8620 if (InitDependOnLC) {
8621 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8622 if (!IS.MinValue || !IS.MaxValue)
8623 return nullptr;
8624 // OuterVar = Min
8625 ExprResult MinValue =
8626 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8627 if (!MinValue.isUsable())
8628 return nullptr;
8629
8630 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8631 IS.CounterVar, MinValue.get());
8632 if (!LBMinVal.isUsable())
8633 return nullptr;
8634 // OuterVar = Min, LBVal
8635 LBMinVal =
8636 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8637 if (!LBMinVal.isUsable())
8638 return nullptr;
8639 // (OuterVar = Min, LBVal)
8640 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8641 if (!LBMinVal.isUsable())
8642 return nullptr;
8643
8644 // OuterVar = Max
8645 ExprResult MaxValue =
8646 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8647 if (!MaxValue.isUsable())
8648 return nullptr;
8649
8650 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8651 IS.CounterVar, MaxValue.get());
8652 if (!LBMaxVal.isUsable())
8653 return nullptr;
8654 // OuterVar = Max, LBVal
8655 LBMaxVal =
8656 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8657 if (!LBMaxVal.isUsable())
8658 return nullptr;
8659 // (OuterVar = Max, LBVal)
8660 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8661 if (!LBMaxVal.isUsable())
8662 return nullptr;
8663
8664 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8665 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8666 if (!LBMin || !LBMax)
8667 return nullptr;
8668 // LB(MinVal) < LB(MaxVal)
8669 ExprResult MinLessMaxRes =
8670 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8671 if (!MinLessMaxRes.isUsable())
8672 return nullptr;
8673 Expr *MinLessMax =
8674 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8675 if (!MinLessMax)
8676 return nullptr;
8677 if (*TestIsLessOp) {
8678 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8679 // LB(MaxVal))
8680 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8681 MinLessMax, LBMin, LBMax);
8682 if (!MinLB.isUsable())
8683 return nullptr;
8684 LBVal = MinLB.get();
8685 } else {
8686 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8687 // LB(MaxVal))
8688 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8689 MinLessMax, LBMax, LBMin);
8690 if (!MaxLB.isUsable())
8691 return nullptr;
8692 LBVal = MaxLB.get();
8693 }
8694 }
8695 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8696 // min(UB(MinVal), UB(MaxVal))
8697 if (CondDependOnLC) {
8698 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8699 if (!IS.MinValue || !IS.MaxValue)
8700 return nullptr;
8701 // OuterVar = Min
8702 ExprResult MinValue =
8703 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8704 if (!MinValue.isUsable())
8705 return nullptr;
8706
8707 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8708 IS.CounterVar, MinValue.get());
8709 if (!UBMinVal.isUsable())
8710 return nullptr;
8711 // OuterVar = Min, UBVal
8712 UBMinVal =
8713 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8714 if (!UBMinVal.isUsable())
8715 return nullptr;
8716 // (OuterVar = Min, UBVal)
8717 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8718 if (!UBMinVal.isUsable())
8719 return nullptr;
8720
8721 // OuterVar = Max
8722 ExprResult MaxValue =
8723 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8724 if (!MaxValue.isUsable())
8725 return nullptr;
8726
8727 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8728 IS.CounterVar, MaxValue.get());
8729 if (!UBMaxVal.isUsable())
8730 return nullptr;
8731 // OuterVar = Max, UBVal
8732 UBMaxVal =
8733 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8734 if (!UBMaxVal.isUsable())
8735 return nullptr;
8736 // (OuterVar = Max, UBVal)
8737 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8738 if (!UBMaxVal.isUsable())
8739 return nullptr;
8740
8741 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8742 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8743 if (!UBMin || !UBMax)
8744 return nullptr;
8745 // UB(MinVal) > UB(MaxVal)
8746 ExprResult MinGreaterMaxRes =
8747 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8748 if (!MinGreaterMaxRes.isUsable())
8749 return nullptr;
8750 Expr *MinGreaterMax =
8751 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8752 if (!MinGreaterMax)
8753 return nullptr;
8754 if (*TestIsLessOp) {
8755 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8756 // UB(MaxVal))
8757 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8758 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8759 if (!MaxUB.isUsable())
8760 return nullptr;
8761 UBVal = MaxUB.get();
8762 } else {
8763 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8764 // UB(MaxVal))
8765 ExprResult MinUB = SemaRef.ActOnConditionalOp(
8766 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8767 if (!MinUB.isUsable())
8768 return nullptr;
8769 UBVal = MinUB.get();
8770 }
8771 }
8772 Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8773 Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8774 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8775 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8776 if (!Upper || !Lower)
8777 return nullptr;
8778
8779 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8780 Step, VarType, TestIsStrictOp,
8781 /*RoundToStep=*/true, Captures);
8782 if (!Diff.isUsable())
8783 return nullptr;
8784
8785 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8786 QualType Type = Diff.get()->getType();
8787 ASTContext &C = SemaRef.Context;
8788 bool UseVarType = VarType->hasIntegerRepresentation() &&
8789 C.getTypeSize(Type) > C.getTypeSize(VarType);
8790 if (!Type->isIntegerType() || UseVarType) {
8791 unsigned NewSize =
8792 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8793 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8794 : Type->hasSignedIntegerRepresentation();
8795 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8796 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8797 Diff = SemaRef.PerformImplicitConversion(
8798 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8799 if (!Diff.isUsable())
8800 return nullptr;
8801 }
8802 }
8803 if (LimitedType) {
8804 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8805 if (NewSize != C.getTypeSize(Type)) {
8806 if (NewSize < C.getTypeSize(Type)) {
8807 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", 8807, __extension__ __PRETTY_FUNCTION__
))
;
8808 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8809 << InitSrcRange << ConditionSrcRange;
8810 }
8811 QualType NewType = C.getIntTypeForBitwidth(
8812 NewSize, Type->hasSignedIntegerRepresentation() ||
8813 C.getTypeSize(Type) < NewSize);
8814 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8815 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8816 Sema::AA_Converting, true);
8817 if (!Diff.isUsable())
8818 return nullptr;
8819 }
8820 }
8821 }
8822
8823 return Diff.get();
8824}
8825
8826std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8827 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8828 // Do not build for iterators, they cannot be used in non-rectangular loop
8829 // nests.
8830 if (LCDecl->getType()->isRecordType())
8831 return std::make_pair(nullptr, nullptr);
8832 // If we subtract, the min is in the condition, otherwise the min is in the
8833 // init value.
8834 Expr *MinExpr = nullptr;
8835 Expr *MaxExpr = nullptr;
8836 Expr *LBExpr = *TestIsLessOp ? LB : UB;
8837 Expr *UBExpr = *TestIsLessOp ? UB : LB;
8838 bool LBNonRect =
8839 *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
8840 bool UBNonRect =
8841 *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
8842 Expr *Lower =
8843 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8844 Expr *Upper =
8845 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8846 if (!Upper || !Lower)
8847 return std::make_pair(nullptr, nullptr);
8848
8849 if (*TestIsLessOp)
8850 MinExpr = Lower;
8851 else
8852 MaxExpr = Upper;
8853
8854 // Build minimum/maximum value based on number of iterations.
8855 QualType VarType = LCDecl->getType().getNonReferenceType();
8856
8857 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8858 Step, VarType, TestIsStrictOp,
8859 /*RoundToStep=*/false, Captures);
8860 if (!Diff.isUsable())
8861 return std::make_pair(nullptr, nullptr);
8862
8863 // ((Upper - Lower [- 1]) / Step) * Step
8864 // Parentheses (for dumping/debugging purposes only).
8865 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8866 if (!Diff.isUsable())
8867 return std::make_pair(nullptr, nullptr);
8868
8869 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8870 if (!NewStep.isUsable())
8871 return std::make_pair(nullptr, nullptr);
8872 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8873 if (!Diff.isUsable())
8874 return std::make_pair(nullptr, nullptr);
8875
8876 // Parentheses (for dumping/debugging purposes only).
8877 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8878 if (!Diff.isUsable())
8879 return std::make_pair(nullptr, nullptr);
8880
8881 // Convert to the ptrdiff_t, if original type is pointer.
8882 if (VarType->isAnyPointerType() &&
8883 !SemaRef.Context.hasSameType(
8884 Diff.get()->getType(),
8885 SemaRef.Context.getUnsignedPointerDiffType())) {
8886 Diff = SemaRef.PerformImplicitConversion(
8887 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8888 Sema::AA_Converting, /*AllowExplicit=*/true);
8889 }
8890 if (!Diff.isUsable())
8891 return std::make_pair(nullptr, nullptr);
8892
8893 if (*TestIsLessOp) {
8894 // MinExpr = Lower;
8895 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8896 Diff = SemaRef.BuildBinOp(
8897 S, DefaultLoc, BO_Add,
8898 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8899 Diff.get());
8900 if (!Diff.isUsable())
8901 return std::make_pair(nullptr, nullptr);
8902 } else {
8903 // MaxExpr = Upper;
8904 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8905 Diff = SemaRef.BuildBinOp(
8906 S, DefaultLoc, BO_Sub,
8907 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8908 Diff.get());
8909 if (!Diff.isUsable())
8910 return std::make_pair(nullptr, nullptr);
8911 }
8912
8913 // Convert to the original type.
8914 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8915 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8916 Sema::AA_Converting,
8917 /*AllowExplicit=*/true);
8918 if (!Diff.isUsable())
8919 return std::make_pair(nullptr, nullptr);
8920
8921 Sema::TentativeAnalysisScope Trap(SemaRef);
8922 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8923 if (!Diff.isUsable())
8924 return std::make_pair(nullptr, nullptr);
8925
8926 if (*TestIsLessOp)
8927 MaxExpr = Diff.get();
8928 else
8929 MinExpr = Diff.get();
8930
8931 return std::make_pair(MinExpr, MaxExpr);
8932}
8933
8934Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8935 if (InitDependOnLC || CondDependOnLC)
8936 return Condition;
8937 return nullptr;
8938}
8939
8940Expr *OpenMPIterationSpaceChecker::buildPreCond(
8941 Scope *S, Expr *Cond,
8942 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8943 // Do not build a precondition when the condition/initialization is dependent
8944 // to prevent pessimistic early loop exit.
8945 // TODO: this can be improved by calculating min/max values but not sure that
8946 // it will be very effective.
8947 if (CondDependOnLC || InitDependOnLC)
19
Taking false branch
8948 return SemaRef
8949 .PerformImplicitConversion(
8950 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8951 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8952 /*AllowExplicit=*/true)
8953 .get();
8954
8955 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8956 Sema::TentativeAnalysisScope Trap(SemaRef);
8957
8958 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
20
Passing null pointer value via 2nd parameter 'Capture'
21
Calling 'tryBuildCapture'
8959 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8960 if (!NewLB.isUsable() || !NewUB.isUsable())
8961 return nullptr;
8962
8963 ExprResult CondExpr =
8964 SemaRef.BuildBinOp(S, DefaultLoc,
8965 *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
8966 : (TestIsStrictOp ? BO_GT : BO_GE),
8967 NewLB.get(), NewUB.get());
8968 if (CondExpr.isUsable()) {
8969 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8970 SemaRef.Context.BoolTy))
8971 CondExpr = SemaRef.PerformImplicitConversion(
8972 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8973 /*AllowExplicit=*/true);
8974 }
8975
8976 // Otherwise use original loop condition and evaluate it in runtime.
8977 return CondExpr.isUsable() ? CondExpr.get() : Cond;
8978}
8979
8980/// Build reference expression to the counter be used for codegen.
8981DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8982 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8983 DSAStackTy &DSA) const {
8984 auto *VD = dyn_cast<VarDecl>(LCDecl);
8985 if (!VD) {
8986 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8987 DeclRefExpr *Ref = buildDeclRefExpr(
8988 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8989 const DSAStackTy::DSAVarData Data =
8990 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8991 // If the loop control decl is explicitly marked as private, do not mark it
8992 // as captured again.
8993 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8994 Captures.insert(std::make_pair(LCRef, Ref));
8995 return Ref;
8996 }
8997 return cast<DeclRefExpr>(LCRef);
8998}
8999
9000Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9001 if (LCDecl && !LCDecl->isInvalidDecl()) {
9002 QualType Type = LCDecl->getType().getNonReferenceType();
9003 VarDecl *PrivateVar = buildVarDecl(
9004 SemaRef, DefaultLoc, Type, LCDecl->getName(),
9005 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9006 isa<VarDecl>(LCDecl)
9007 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9008 : nullptr);
9009 if (PrivateVar->isInvalidDecl())
9010 return nullptr;
9011 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9012 }
9013 return nullptr;
9014}
9015
9016/// Build initialization of the counter to be used for codegen.
9017Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9018
9019/// Build step of the counter be used for codegen.
9020Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9021
9022Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9023 Scope *S, Expr *Counter,
9024 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9025 Expr *Inc, OverloadedOperatorKind OOK) {
9026 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9027 if (!Cnt)
9028 return nullptr;
9029 if (Inc) {
9030 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", 9031, __extension__ __PRETTY_FUNCTION__
))
9031 "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", 9031, __extension__ __PRETTY_FUNCTION__
))
;
9032 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9033 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9034 if (!Cnt)
9035 return nullptr;
9036 }
9037 QualType VarType = LCDecl->getType().getNonReferenceType();
9038 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9039 !SemaRef.getLangOpts().CPlusPlus)
9040 return nullptr;
9041 // Upper - Lower
9042 Expr *Upper =
9043 *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9044 Expr *Lower =
9045 *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9046 if (!Upper || !Lower)
9047 return nullptr;
9048
9049 ExprResult Diff = calculateNumIters(
9050 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9051 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9052 if (!Diff.isUsable())
9053 return nullptr;
9054
9055 return Diff.get();
9056}
9057} // namespace
9058
9059void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9060 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", 9060, __extension__ __PRETTY_FUNCTION__
))
;
9061 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", 9061, __extension__ __PRETTY_FUNCTION__
))
;
9062 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
9063 if (AssociatedLoops > 0 &&
9064 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
9065 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
9066 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9067 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
9068 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9069 if (ValueDecl *D = ISC.getLoopDecl()) {
9070 auto *VD = dyn_cast<VarDecl>(D);
9071 DeclRefExpr *PrivateRef = nullptr;
9072 if (!VD) {
9073 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9074 VD = Private;
9075 } else {
9076 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9077 /*WithInit=*/false);
9078 VD = cast<VarDecl>(PrivateRef->getDecl());
9079 }
9080 }
9081 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
9082 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
9083 if (LD != D->getCanonicalDecl()) {
9084 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
9085 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9086 MarkDeclarationsReferencedInExpr(
9087 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9088 Var->getType().getNonLValueExprType(Context),
9089 ForLoc, /*RefersToCapture=*/true));
9090 }
9091 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
9092 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9093 // Referenced in a Construct, C/C++]. The loop iteration variable in the
9094 // associated for-loop of a simd construct with just one associated
9095 // for-loop may be listed in a linear clause with a constant-linear-step
9096 // that is the increment of the associated for-loop. The loop iteration
9097 // variable(s) in the associated for-loop(s) of a for or parallel for
9098 // construct may be listed in a private or lastprivate clause.
9099 DSAStackTy::DSAVarData DVar =
9100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
9101 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9102 // is declared in the loop and it is predetermined as a private.
9103 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9104 OpenMPClauseKind PredeterminedCKind =
9105 isOpenMPSimdDirective(DKind)
9106 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9107 : OMPC_private;
9108 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9109 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9110 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9111 DVar.CKind != OMPC_private))) ||
9112 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9113 DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9114 DKind == OMPD_parallel_master_taskloop ||
9115 DKind == OMPD_parallel_masked_taskloop ||
9116 isOpenMPDistributeDirective(DKind)) &&
9117 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9118 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9119 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9120 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9121 << getOpenMPClauseName(DVar.CKind)
9122 << getOpenMPDirectiveName(DKind)
9123 << getOpenMPClauseName(PredeterminedCKind);
9124 if (DVar.RefExpr == nullptr)
9125 DVar.CKind = PredeterminedCKind;
9126 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
9127 /*IsLoopIterVar=*/true);
9128 } else if (LoopDeclRefExpr) {
9129 // Make the loop iteration variable private (for worksharing
9130 // constructs), linear (for simd directives with the only one
9131 // associated loop) or lastprivate (for simd directives with several
9132 // collapsed or ordered loops).
9133 if (DVar.CKind == OMPC_unknown)
9134 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9135 PrivateRef);
9136 }
9137 }
9138 }
9139 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
9140 }
9141}
9142
9143/// Called on a for stmt to check and extract its iteration space
9144/// for further processing (such as collapsing).
9145static bool checkOpenMPIterationSpace(
9146 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9147 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9148 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9149 Expr *OrderedLoopCountExpr,
9150 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9151 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9152 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9153 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
2
Assuming the condition is false
9154 // OpenMP [2.9.1, Canonical Loop Form]
9155 // for (init-expr; test-expr; incr-expr) structured-block
9156 // for (range-decl: range-expr) structured-block
9157 if (auto *CanonLoop
3.1
'CanonLoop' is null
= dyn_cast_or_null<OMPCanonicalLoop>(S))
3
Assuming 'S' is not a 'CastReturnType'
4
Taking false branch
9158 S = CanonLoop->getLoopStmt();
9159 auto *For = dyn_cast_or_null<ForStmt>(S);
5
Assuming 'S' is a 'CastReturnType'
9160 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
6
Assuming 'S' is not a 'CastReturnType'
9161 // Ranged for is supported only in OpenMP 5.0.
9162 if (!For
6.1
'For' is non-null
&& (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9163 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9164 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9165 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9166 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9167 if (TotalNestedLoopCount > 1) {
9168 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9169 SemaRef.Diag(DSA.getConstructLoc(),
9170 diag::note_omp_collapse_ordered_expr)
9171 << 2 << CollapseLoopCountExpr->getSourceRange()
9172 << OrderedLoopCountExpr->getSourceRange();
9173 else if (CollapseLoopCountExpr)
9174 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9175 diag::note_omp_collapse_ordered_expr)
9176 << 0 << CollapseLoopCountExpr->getSourceRange();
9177 else
9178 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9179 diag::note_omp_collapse_ordered_expr)
9180 << 1 << OrderedLoopCountExpr->getSourceRange();
9181 }
9182 return true;
9183 }
9184 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", 9185, __extension__ __PRETTY_FUNCTION__
))
7
Assuming the condition is true
8
'?' condition is true
9185 "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", 9185, __extension__ __PRETTY_FUNCTION__
))
;
9186 // Postpone analysis in dependent contexts for ranged for loops.
9187 if (CXXFor
8.1
'CXXFor' is null
&& SemaRef.CurContext->isDependentContext())
9188 return false;
9189
9190 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
10
Calling constructor for 'OpenMPIterationSpaceChecker'
12
Returning from constructor for 'OpenMPIterationSpaceChecker'
9191 For
8.2
'For' is non-null
? For->getForLoc() : CXXFor->getForLoc())
;
9
'?' condition is true
9192
9193 // Check init.
9194 Stmt *Init = For
12.1
'For' is non-null
? For->getInit() : CXXFor->getBeginStmt();
13
'?' condition is true
9195 if (ISC.checkAndSetInit(Init))
14
Taking false branch
9196 return true;
9197
9198 bool HasErrors = false;
9199
9200 // Check loop variable's type.
9201 if (ValueDecl *LCDecl
14.1
'LCDecl' is null
= ISC.getLoopDecl()) {
9202 // OpenMP [2.6, Canonical Loop Form]
9203 // Var is one of the following:
9204 // A variable of signed or unsigned integer type.
9205 // For C++, a variable of a random access iterator type.
9206 // For C, a variable of a pointer type.
9207 QualType VarType = LCDecl->getType().getNonReferenceType();
9208 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9209 !VarType->isPointerType() &&
9210 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9211 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9212 << SemaRef.getLangOpts().CPlusPlus;
9213 HasErrors = true;
9214 }
9215
9216 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9217 // a Construct
9218 // The loop iteration variable(s) in the associated for-loop(s) of a for or
9219 // parallel for construct is (are) private.
9220 // The loop iteration variable in the associated for-loop of a simd
9221 // construct with just one associated for-loop is linear with a
9222 // constant-linear-step that is the increment of the associated for-loop.
9223 // Exclude loop var from the list of variables with implicitly defined data
9224 // sharing attributes.
9225 VarsWithImplicitDSA.erase(LCDecl);
9226
9227 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", 9227, __extension__ __PRETTY_FUNCTION__
))
;
9228
9229 // Check test-expr.
9230 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9231
9232 // Check incr-expr.
9233 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9234 }
9235
9236 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors
15.1
'HasErrors' is false
)
15
Assuming the condition is false
16
Taking false branch
9237 return HasErrors;
9238
9239 // Build the loop's iteration space representation.
9240 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
18
Calling 'OpenMPIterationSpaceChecker::buildPreCond'
9241 DSA.getCurScope(), For
16.1
'For' is non-null
? For->getCond() : CXXFor->getCond(), Captures)
;
17
'?' condition is true
9242 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9243 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9244 (isOpenMPWorksharingDirective(DKind) ||
9245 isOpenMPGenericLoopDirective(DKind) ||
9246 isOpenMPTaskLoopDirective(DKind) ||
9247 isOpenMPDistributeDirective(DKind) ||
9248 isOpenMPLoopTransformationDirective(DKind)),
9249 Captures);
9250 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9251 ISC.buildCounterVar(Captures, DSA);
9252 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9253 ISC.buildPrivateCounterVar();
9254 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9255 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9256 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9257 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9258 ISC.getConditionSrcRange();
9259 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9260 ISC.getIncrementSrcRange();
9261 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9262 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9263 ISC.isStrictTestOp();
9264 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9265 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9266 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9267 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9268 ISC.buildFinalCondition(DSA.getCurScope());
9269 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9270 ISC.doesInitDependOnLC();
9271 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9272 ISC.doesCondDependOnLC();
9273 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9274 ISC.getLoopDependentIdx();
9275
9276 HasErrors |=
9277 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9278 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9279 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9280 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9281 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9282 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9283 if (!HasErrors && DSA.isOrderedRegion()) {
9284 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9285 if (CurrentNestedLoopCount <
9286 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9287 DSA.getOrderedRegionParam().second->setLoopNumIterations(
9288 CurrentNestedLoopCount,
9289 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9290 DSA.getOrderedRegionParam().second->setLoopCounter(
9291 CurrentNestedLoopCount,
9292 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9293 }
9294 }
9295 for (auto &Pair : DSA.getDoacrossDependClauses()) {
9296 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
9297 // Erroneous case - clause has some problems.
9298 continue;
9299 }
9300 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
9301 Pair.second.size() <= CurrentNestedLoopCount) {
9302 // Erroneous case - clause has some problems.
9303 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
9304 continue;
9305 }
9306 Expr *CntValue;
9307 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
9308 CntValue = ISC.buildOrderedLoopData(
9309 DSA.getCurScope(),
9310 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9311 Pair.first->getDependencyLoc());
9312 else
9313 CntValue = ISC.buildOrderedLoopData(
9314 DSA.getCurScope(),
9315 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9316 Pair.first->getDependencyLoc(),
9317 Pair.second[CurrentNestedLoopCount].first,
9318 Pair.second[CurrentNestedLoopCount].second);
9319 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
9320 }
9321 }
9322
9323 return HasErrors;
9324}
9325
9326/// Build 'VarRef = Start.
9327static ExprResult
9328buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9329 ExprResult Start, bool IsNonRectangularLB,
9330 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9331 // Build 'VarRef = Start.
9332 ExprResult NewStart = IsNonRectangularLB
9333 ? Start.get()
9334 : tryBuildCapture(SemaRef, Start.get(), Captures);
9335 if (!NewStart.isUsable())
9336 return ExprError();
9337 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9338 VarRef.get()->getType())) {
9339 NewStart = SemaRef.PerformImplicitConversion(
9340 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9341 /*AllowExplicit=*/true);
9342 if (!NewStart.isUsable())
9343 return ExprError();
9344 }
9345
9346 ExprResult Init =
9347 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9348 return Init;
9349}
9350
9351/// Build 'VarRef = Start + Iter * Step'.
9352static ExprResult buildCounterUpdate(
9353 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9354 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9355 bool IsNonRectangularLB,
9356 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9357 // Add parentheses (for debugging purposes only).
9358 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9359 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9360 !Step.isUsable())
9361 return ExprError();
9362
9363 ExprResult NewStep = Step;
9364 if (Captures)
9365 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9366 if (NewStep.isInvalid())
9367 return ExprError();
9368 ExprResult Update =
9369 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9370 if (!Update.isUsable())
9371 return ExprError();
9372
9373 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9374 // 'VarRef = Start (+|-) Iter * Step'.
9375 if (!Start.isUsable())
9376 return ExprError();
9377 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9378 if (!NewStart.isUsable())
9379 return ExprError();
9380 if (Captures && !IsNonRectangularLB)
9381 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9382 if (NewStart.isInvalid())
9383 return ExprError();
9384
9385 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9386 ExprResult SavedUpdate = Update;
9387 ExprResult UpdateVal;
9388 if (VarRef.get()->getType()->isOverloadableType() ||
9389 NewStart.get()->getType()->isOverloadableType() ||
9390 Update.get()->getType()->isOverloadableType()) {
9391 Sema::TentativeAnalysisScope Trap(SemaRef);
9392
9393 Update =
9394 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9395 if (Update.isUsable()) {
9396 UpdateVal =
9397 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9398 VarRef.get(), SavedUpdate.get());
9399 if (UpdateVal.isUsable()) {
9400 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9401 UpdateVal.get());
9402 }
9403 }
9404 }
9405
9406 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9407 if (!Update.isUsable() || !UpdateVal.isUsable()) {
9408 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9409 NewStart.get(), SavedUpdate.get());
9410 if (!Update.isUsable())
9411 return ExprError();
9412
9413 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9414 VarRef.get()->getType())) {
9415 Update = SemaRef.PerformImplicitConversion(
9416 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9417 if (!Update.isUsable())
9418 return ExprError();
9419 }
9420
9421 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9422 }
9423 return Update;
9424}
9425
9426/// Convert integer expression \a E to make it have at least \a Bits
9427/// bits.
9428static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9429 if (E == nullptr)
9430 return ExprError();
9431 ASTContext &C = SemaRef.Context;
9432 QualType OldType = E->getType();
9433 unsigned HasBits = C.getTypeSize(OldType);
9434 if (HasBits >= Bits)
9435 return ExprResult(E);
9436 // OK to convert to signed, because new type has more bits than old.
9437 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9438 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9439 true);
9440}
9441
9442/// Check if the given expression \a E is a constant integer that fits
9443/// into \a Bits bits.
9444static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9445 if (E == nullptr)
9446 return false;
9447 if (Optional<llvm::APSInt> Result =
9448 E->getIntegerConstantExpr(SemaRef.Context))
9449 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9450 return false;
9451}
9452
9453/// Build preinits statement for the given declarations.
9454static Stmt *buildPreInits(ASTContext &Context,
9455 MutableArrayRef<Decl *> PreInits) {
9456 if (!PreInits.empty()) {
9457 return new (Context) DeclStmt(
9458 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9459 SourceLocation(), SourceLocation());
9460 }
9461 return nullptr;
9462}
9463
9464/// Build preinits statement for the given declarations.
9465static Stmt *
9466buildPreInits(ASTContext &Context,
9467 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9468 if (!Captures.empty()) {
9469 SmallVector<Decl *, 16> PreInits;
9470 for (const auto &Pair : Captures)
9471 PreInits.push_back(Pair.second->getDecl());
9472 return buildPreInits(Context, PreInits);
9473 }
9474 return nullptr;
9475}
9476
9477/// Build postupdate expression for the given list of postupdates expressions.
9478static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9479 Expr *PostUpdate = nullptr;
9480 if (!PostUpdates.empty()) {
9481 for (Expr *E : PostUpdates) {
9482 Expr *ConvE = S.BuildCStyleCastExpr(
9483 E->getExprLoc(),
9484 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9485 E->getExprLoc(), E)
9486 .get();
9487 PostUpdate = PostUpdate
9488 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9489 PostUpdate, ConvE)
9490 .get()
9491 : ConvE;
9492 }
9493 }
9494 return PostUpdate;
9495}
9496
9497/// Called on a for stmt to check itself and nested loops (if any).
9498/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9499/// number of collapsed loops otherwise.
9500static unsigned
9501checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9502 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9503 DSAStackTy &DSA,
9504 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9505 OMPLoopBasedDirective::HelperExprs &Built) {
9506 unsigned NestedLoopCount = 1;
9507 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9508 !isOpenMPLoopTransformationDirective(DKind);
9509
9510 if (CollapseLoopCountExpr) {
9511 // Found 'collapse' clause - calculate collapse number.
9512 Expr::EvalResult Result;
9513 if (!CollapseLoopCountExpr->isValueDependent() &&
9514 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9515 NestedLoopCount = Result.Val.getInt().getLimitedValue();
9516 } else {
9517 Built.clear(/*Size=*/1);
9518 return 1;
9519 }
9520 }
9521 unsigned OrderedLoopCount = 1;
9522 if (OrderedLoopCountExpr) {
9523 // Found 'ordered' clause - calculate collapse number.
9524 Expr::EvalResult EVResult;
9525 if (!OrderedLoopCountExpr->isValueDependent() &&
9526 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9527 SemaRef.getASTContext())) {
9528 llvm::APSInt Result = EVResult.Val.getInt();
9529 if (Result.getLimitedValue() < NestedLoopCount) {
9530 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9531 diag::err_omp_wrong_ordered_loop_count)
9532 << OrderedLoopCountExpr->getSourceRange();
9533 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9534 diag::note_collapse_loop_count)
9535 << CollapseLoopCountExpr->getSourceRange();
9536 }
9537 OrderedLoopCount = Result.getLimitedValue();
9538 } else {
9539 Built.clear(/*Size=*/1);
9540 return 1;
9541 }
9542 }
9543 // This is helper routine for loop directives (e.g., 'for', 'simd',
9544 // 'for simd', etc.).
9545 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9546 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9547 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9548 if (!OMPLoopBasedDirective::doForAllLoops(
9549 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9550 SupportsNonPerfectlyNested, NumLoops,
9551 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9552 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9553 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9554 if (checkOpenMPIterationSpace(
1
Calling 'checkOpenMPIterationSpace'
9555 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9556 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9557 VarsWithImplicitDSA, IterSpaces, Captures))
9558 return true;
9559 if (Cnt > 0 && Cnt >= NestedLoopCount &&
9560 IterSpaces[Cnt].CounterVar) {
9561 // Handle initialization of captured loop iterator variables.
9562 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9563 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9564 Captures[DRE] = DRE;
9565 }
9566 }
9567 return false;
9568 },
9569 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9570 Stmt *DependentPreInits = Transform->getPreInits();
9571 if (!DependentPreInits)
9572 return;
9573 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9574 auto *D = cast<VarDecl>(C);
9575 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9576 Transform->getBeginLoc());
9577 Captures[Ref] = Ref;
9578 }
9579 }))
9580 return 0;
9581
9582 Built.clear(/* size */ NestedLoopCount);
9583
9584 if (SemaRef.CurContext->isDependentContext())
9585 return NestedLoopCount;
9586
9587 // An example of what is generated for the following code:
9588 //
9589 // #pragma omp simd collapse(2) ordered(2)
9590 // for (i = 0; i < NI; ++i)
9591 // for (k = 0; k < NK; ++k)
9592 // for (j = J0; j < NJ; j+=2) {
9593 // <loop body>
9594 // }
9595 //
9596 // We generate the code below.
9597 // Note: the loop body may be outlined in CodeGen.
9598 // Note: some counters may be C++ classes, operator- is used to find number of
9599 // iterations and operator+= to calculate counter value.
9600 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9601 // or i64 is currently supported).
9602 //
9603 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9604 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9605 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9606 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9607 // // similar updates for vars in clauses (e.g. 'linear')
9608 // <loop body (using local i and j)>
9609 // }
9610 // i = NI; // assign final values of counters
9611 // j = NJ;
9612 //
9613
9614 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9615 // the iteration counts of the collapsed for loops.
9616 // Precondition tests if there is at least one iteration (all conditions are
9617 // true).
9618 auto PreCond = ExprResult(IterSpaces[0].PreCond);
9619 Expr *N0 = IterSpaces[0].NumIterations;
9620 ExprResult LastIteration32 =
9621 widenIterationCount(/*Bits=*/32,
9622 SemaRef
9623 .PerformImplicitConversion(
9624 N0->IgnoreImpCasts(), N0->getType(),
9625 Sema::AA_Converting, /*AllowExplicit=*/true)
9626 .get(),
9627 SemaRef);
9628 ExprResult LastIteration64 = widenIterationCount(
9629 /*Bits=*/64,
9630 SemaRef
9631 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9632 Sema::AA_Converting,
9633 /*AllowExplicit=*/true)
9634 .get(),
9635 SemaRef);
9636
9637 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9638 return NestedLoopCount;
9639
9640 ASTContext &C = SemaRef.Context;
9641 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9642
9643 Scope *CurScope = DSA.getCurScope();
9644 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9645 if (PreCond.isUsable()) {
9646 PreCond =
9647 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9648 PreCond.get(), IterSpaces[Cnt].PreCond);
9649 }
9650 Expr *N = IterSpaces[Cnt].NumIterations;
9651 SourceLocation Loc = N->getExprLoc();
9652 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9653 if (LastIteration32.isUsable())
9654 LastIteration32 = SemaRef.BuildBinOp(
9655 CurScope, Loc, BO_Mul, LastIteration32.get(),
9656 SemaRef
9657 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9658 Sema::AA_Converting,
9659 /*AllowExplicit=*/true)
9660 .get());
9661 if (LastIteration64.isUsable())
9662 LastIteration64 = SemaRef.BuildBinOp(
9663 CurScope, Loc, BO_Mul, LastIteration64.get(),
9664 SemaRef
9665 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9666 Sema::AA_Converting,
9667 /*AllowExplicit=*/true)
9668 .get());
9669 }
9670
9671 // Choose either the 32-bit or 64-bit version.
9672 ExprResult LastIteration = LastIteration64;
9673 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9674 (LastIteration32.isUsable() &&
9675 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9676 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9677 fitsInto(
9678 /*Bits=*/32,
9679 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9680 LastIteration64.get(), SemaRef))))
9681 LastIteration = LastIteration32;
9682 QualType VType = LastIteration.get()->getType();
9683 QualType RealVType = VType;
9684 QualType StrideVType = VType;
9685 if (isOpenMPTaskLoopDirective(DKind)) {
9686 VType =
9687 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9688 StrideVType =
9689 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9690 }
9691
9692 if (!LastIteration.isUsable())
9693 return 0;
9694
9695 // Save the number of iterations.
9696 ExprResult NumIterations = LastIteration;
9697 {
9698 LastIteration = SemaRef.BuildBinOp(
9699 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9700 LastIteration.get(),
9701 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9702 if (!LastIteration.isUsable())
9703 return 0;
9704 }
9705
9706 // Calculate the last iteration number beforehand instead of doing this on
9707 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9708 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9709 ExprResult CalcLastIteration;
9710 if (!IsConstant) {
9711 ExprResult SaveRef =
9712 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9713 LastIteration = SaveRef;
9714
9715 // Prepare SaveRef + 1.
9716 NumIterations = SemaRef.BuildBinOp(
9717 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9718 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9719 if (!NumIterations.isUsable())
9720 return 0;
9721 }
9722
9723 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9724
9725 // Build variables passed into runtime, necessary for worksharing directives.
9726 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9727 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9728 isOpenMPDistributeDirective(DKind) ||
9729 isOpenMPGenericLoopDirective(DKind) ||
9730 isOpenMPLoopTransformationDirective(DKind)) {
9731 // Lower bound variable, initialized with zero.
9732 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9733 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9734 SemaRef.AddInitializerToDecl(LBDecl,
9735 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9736 /*DirectInit*/ false);
9737
9738 // Upper bound variable, initialized with last iteration number.
9739 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9740 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9741 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9742 /*DirectInit*/ false);
9743
9744 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9745 // This will be used to implement clause 'lastprivate'.
9746 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9747 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9748 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9749 SemaRef.AddInitializerToDecl(ILDecl,
9750 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9751 /*DirectInit*/ false);
9752
9753 // Stride variable returned by runtime (we initialize it to 1 by default).
9754 VarDecl *STDecl =
9755 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9756 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9757 SemaRef.AddInitializerToDecl(STDecl,
9758 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9759 /*DirectInit*/ false);
9760
9761 // Build expression: UB = min(UB, LastIteration)
9762 // It is necessary for CodeGen of directives with static scheduling.
9763 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9764 UB.get(), LastIteration.get());
9765 ExprResult CondOp = SemaRef.ActOnConditionalOp(
9766 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9767 LastIteration.get(), UB.get());
9768 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9769 CondOp.get());
9770 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9771
9772 // If we have a combined directive that combines 'distribute', 'for' or
9773 // 'simd' we need to be able to access the bounds of the schedule of the
9774 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9775 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9776 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9777 // Lower bound variable, initialized with zero.
9778 VarDecl *CombLBDecl =
9779 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9780 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9781 SemaRef.AddInitializerToDecl(
9782 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9783 /*DirectInit*/ false);
9784
9785 // Upper bound variable, initialized with last iteration number.
9786 VarDecl *CombUBDecl =
9787 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9788 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9789 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9790 /*DirectInit*/ false);
9791
9792 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9793 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9794 ExprResult CombCondOp =
9795 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9796 LastIteration.get(), CombUB.get());
9797 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9798 CombCondOp.get());
9799 CombEUB =
9800 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9801
9802 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9803 // We expect to have at least 2 more parameters than the 'parallel'
9804 // directive does - the lower and upper bounds of the previous schedule.
9805 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", 9806, __extension__ __PRETTY_FUNCTION__
))
9806 "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", 9806, __extension__ __PRETTY_FUNCTION__
))
;
9807
9808 // Set the proper type for the bounds given what we learned from the
9809 // enclosed loops.
9810 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9811 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9812
9813 // Previous lower and upper bounds are obtained from the region
9814 // parameters.
9815 PrevLB =
9816 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9817 PrevUB =
9818 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9819 }
9820 }
9821
9822 // Build the iteration variable and its initialization before loop.
9823 ExprResult IV;
9824 ExprResult Init, CombInit;
9825 {
9826 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9827 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9828 Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9829 isOpenMPGenericLoopDirective(DKind) ||
9830 isOpenMPTaskLoopDirective(DKind) ||
9831 isOpenMPDistributeDirective(DKind) ||
9832 isOpenMPLoopTransformationDirective(DKind))
9833 ? LB.get()
9834 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9835 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9836 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9837
9838 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9839 Expr *CombRHS =
9840 (isOpenMPWorksharingDirective(DKind) ||
9841 isOpenMPGenericLoopDirective(DKind) ||
9842 isOpenMPTaskLoopDirective(DKind) ||
9843 isOpenMPDistributeDirective(DKind))
9844 ? CombLB.get()
9845 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9846 CombInit =
9847 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9848 CombInit =
9849 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9850 }
9851 }
9852
9853 bool UseStrictCompare =
9854 RealVType->hasUnsignedIntegerRepresentation() &&
9855 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9856 return LIS.IsStrictCompare;
9857 });
9858 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9859 // unsigned IV)) for worksharing loops.
9860 SourceLocation CondLoc = AStmt->getBeginLoc();
9861 Expr *BoundUB = UB.get();
9862 if (UseStrictCompare) {
9863 BoundUB =
9864 SemaRef
9865 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9866 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9867 .get();
9868 BoundUB =
9869 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9870 }
9871 ExprResult Cond =
9872 (isOpenMPWorksharingDirective(DKind) ||
9873 isOpenMPGenericLoopDirective(DKind) ||
9874 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9875 isOpenMPLoopTransformationDirective(DKind))
9876 ? SemaRef.BuildBinOp(CurScope, CondLoc,
9877 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9878 BoundUB)
9879 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9880 NumIterations.get());
9881 ExprResult CombDistCond;
9882 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9883 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9884 NumIterations.get());
9885 }
9886
9887 ExprResult CombCond;
9888 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9889 Expr *BoundCombUB = CombUB.get();
9890 if (UseStrictCompare) {
9891 BoundCombUB =
9892 SemaRef
9893 .BuildBinOp(
9894 CurScope, CondLoc, BO_Add, BoundCombUB,
9895 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9896 .get();
9897 BoundCombUB =
9898 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9899 .get();
9900 }
9901 CombCond =
9902 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9903 IV.get(), BoundCombUB);
9904 }
9905 // Loop increment (IV = IV + 1)
9906 SourceLocation IncLoc = AStmt->getBeginLoc();
9907 ExprResult Inc =
9908 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9909 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9910 if (!Inc.isUsable())
9911 return 0;
9912 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9913 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9914 if (!Inc.isUsable())
9915 return 0;
9916
9917 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9918 // Used for directives with static scheduling.
9919 // In combined construct, add combined version that use CombLB and CombUB
9920 // base variables for the update
9921 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9922 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9923 isOpenMPGenericLoopDirective(DKind) ||
9924 isOpenMPDistributeDirective(DKind) ||
9925 isOpenMPLoopTransformationDirective(DKind)) {
9926 // LB + ST
9927 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9928 if (!NextLB.isUsable())
9929 return 0;
9930 // LB = LB + ST
9931 NextLB =
9932 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9933 NextLB =
9934 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9935 if (!NextLB.isUsable())
9936 return 0;
9937 // UB + ST
9938 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9939 if (!NextUB.isUsable())
9940 return 0;
9941 // UB = UB + ST
9942 NextUB =
9943 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9944 NextUB =
9945 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9946 if (!NextUB.isUsable())
9947 return 0;
9948 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9949 CombNextLB =
9950 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9951 if (!NextLB.isUsable())
9952 return 0;
9953 // LB = LB + ST
9954 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9955 CombNextLB.get());
9956 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9957 /*DiscardedValue*/ false);
9958 if (!CombNextLB.isUsable())
9959 return 0;
9960 // UB + ST
9961 CombNextUB =
9962 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9963 if (!CombNextUB.isUsable())
9964 return 0;
9965 // UB = UB + ST
9966 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9967 CombNextUB.get());
9968 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9969 /*DiscardedValue*/ false);
9970 if (!CombNextUB.isUsable())
9971 return 0;
9972 }
9973 }
9974
9975 // Create increment expression for distribute loop when combined in a same
9976 // directive with for as IV = IV + ST; ensure upper bound expression based
9977 // on PrevUB instead of NumIterations - used to implement 'for' when found
9978 // in combination with 'distribute', like in 'distribute parallel for'
9979 SourceLocation DistIncLoc = AStmt->getBeginLoc();
9980 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9981 if (isOpenMPLoopBoundSharingDirective(DKind)) {
9982 DistCond = SemaRef.BuildBinOp(
9983 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9984 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", 9984, __extension__ __PRETTY_FUNCTION__
))
;
9985
9986 DistInc =
9987 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9988 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", 9988, __extension__ __PRETTY_FUNCTION__
))
;
9989 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9990 DistInc.get());
9991 DistInc =
9992 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9993 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", 9993, __extension__ __PRETTY_FUNCTION__
))
;
9994
9995 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9996 // construct
9997 ExprResult NewPrevUB = PrevUB;
9998 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9999 if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10000 PrevUB.get()->getType())) {
10001 NewPrevUB = SemaRef.BuildCStyleCastExpr(
10002 DistEUBLoc,
10003 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10004 DistEUBLoc, NewPrevUB.get());
10005 if (!NewPrevUB.isUsable())
10006 return 0;
10007 }
10008 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10009 UB.get(), NewPrevUB.get());
10010 ExprResult CondOp = SemaRef.ActOnConditionalOp(
10011 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10012 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10013 CondOp.get());
10014 PrevEUB =
10015 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10016
10017 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10018 // parallel for is in combination with a distribute directive with
10019 // schedule(static, 1)
10020 Expr *BoundPrevUB = PrevUB.get();
10021 if (UseStrictCompare) {
10022 BoundPrevUB =
10023 SemaRef
10024 .BuildBinOp(
10025 CurScope, CondLoc, BO_Add, BoundPrevUB,
10026 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10027 .get();
10028 BoundPrevUB =
10029 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10030 .get();
10031 }
10032 ParForInDistCond =
10033 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10034 IV.get(), BoundPrevUB);
10035 }
10036
10037 // Build updates and final values of the loop counters.
10038 bool HasErrors = false;
10039 Built.Counters.resize(NestedLoopCount);
10040 Built.Inits.resize(NestedLoopCount);
10041 Built.Updates.resize(NestedLoopCount);
10042 Built.Finals.resize(NestedLoopCount);
10043 Built.DependentCounters.resize(NestedLoopCount);
10044 Built.DependentInits.resize(NestedLoopCount);
10045 Built.FinalsConditions.resize(NestedLoopCount);
10046 {
10047 // We implement the following algorithm for obtaining the
10048 // original loop iteration variable values based on the
10049 // value of the collapsed loop iteration variable IV.
10050 //
10051 // Let n+1 be the number of collapsed loops in the nest.
10052 // Iteration variables (I0, I1, .... In)
10053 // Iteration counts (N0, N1, ... Nn)
10054 //
10055 // Acc = IV;
10056 //
10057 // To compute Ik for loop k, 0 <= k <= n, generate:
10058 // Prod = N(k+1) * N(k+2) * ... * Nn;
10059 // Ik = Acc / Prod;
10060 // Acc -= Ik * Prod;
10061 //
10062 ExprResult Acc = IV;
10063 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10064 LoopIterationSpace &IS = IterSpaces[Cnt];
10065 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10066 ExprResult Iter;
10067
10068 // Compute prod
10069 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10070 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10071 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10072 IterSpaces[K].NumIterations);
10073
10074 // Iter = Acc / Prod
10075 // If there is at least one more inner loop to avoid
10076 // multiplication by 1.
10077 if (Cnt + 1 < NestedLoopCount)
10078 Iter =
10079 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10080 else
10081 Iter = Acc;
10082 if (!Iter.isUsable()) {
10083 HasErrors = true;
10084 break;
10085 }
10086
10087 // Update Acc:
10088 // Acc -= Iter * Prod
10089 // Check if there is at least one more inner loop to avoid
10090 // multiplication by 1.
10091 if (Cnt + 1 < NestedLoopCount)
10092 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10093 Prod.get());
10094 else
10095 Prod = Iter;
10096 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10097
10098 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10099 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10100 DeclRefExpr *CounterVar = buildDeclRefExpr(
10101 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10102 /*RefersToCapture=*/true);
10103 ExprResult Init =
10104 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10105 IS.CounterInit, IS.IsNonRectangularLB, Captures);
10106 if (!Init.isUsable()) {
10107 HasErrors = true;
10108 break;
10109 }
10110 ExprResult Update = buildCounterUpdate(
10111 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10112 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10113 if (!Update.isUsable()) {
10114 HasErrors = true;
10115 break;
10116 }
10117
10118 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10119 ExprResult Final =
10120 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10121 IS.CounterInit, IS.NumIterations, IS.CounterStep,
10122 IS.Subtract, IS.IsNonRectangularLB, &Captures);
10123 if (!Final.isUsable()) {
10124 HasErrors = true;
10125 break;
10126 }
10127
10128 if (!Update.isUsable() || !Final.isUsable()) {
10129 HasErrors = true;
10130 break;
10131 }
10132 // Save results
10133 Built.Counters[Cnt] = IS.CounterVar;
10134 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10135 Built.Inits[Cnt] = Init.get();
10136 Built.Updates[Cnt] = Update.get();
10137 Built.Finals[Cnt] = Final.get();
10138 Built.DependentCounters[Cnt] = nullptr;
10139 Built.DependentInits[Cnt] = nullptr;
10140 Built.FinalsConditions[Cnt] = nullptr;
10141 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10142 Built.DependentCounters[Cnt] =
10143 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
10144 Built.DependentInits[Cnt] =
10145 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
10146 Built.FinalsConditions[Cnt] = IS.FinalCondition;
10147 }
10148 }
10149 }
10150
10151 if (HasErrors)
10152 return 0;
10153
10154 // Save results
10155 Built.IterationVarRef = IV.get();
10156 Built.LastIteration = LastIteration.get();
10157 Built.NumIterations = NumIterations.get();
10158 Built.CalcLastIteration = SemaRef
10159 .ActOnFinishFullExpr(CalcLastIteration.get(),
10160 /*DiscardedValue=*/false)
10161 .get();
10162 Built.PreCond = PreCond.get();
10163 Built.PreInits = buildPreInits(C, Captures);
10164 Built.Cond = Cond.get();
10165 Built.Init = Init.get();
10166 Built.Inc = Inc.get();
10167 Built.LB = LB.get();
10168 Built.UB = UB.get();
10169 Built.IL = IL.get();
10170 Built.ST = ST.get();
10171 Built.EUB = EUB.get();
10172 Built.NLB = NextLB.get();
10173 Built.NUB = NextUB.get();
10174 Built.PrevLB = PrevLB.get();
10175 Built.PrevUB = PrevUB.get();
10176 Built.DistInc = DistInc.get();
10177 Built.PrevEUB = PrevEUB.get();
10178 Built.DistCombinedFields.LB = CombLB.get();
10179 Built.DistCombinedFields.UB = CombUB.get();
10180 Built.DistCombinedFields.EUB = CombEUB.get();
10181 Built.DistCombinedFields.Init = CombInit.get();
10182 Built.DistCombinedFields.Cond = CombCond.get();
10183 Built.DistCombinedFields.NLB = CombNextLB.get();
10184 Built.DistCombinedFields.NUB = CombNextUB.get();
10185 Built.DistCombinedFields.DistCond = CombDistCond.get();
10186 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10187
10188 return NestedLoopCount;
10189}
10190
10191static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10192 auto CollapseClauses =
10193 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10194 if (CollapseClauses.begin() != CollapseClauses.end())
10195 return (*CollapseClauses.begin())->getNumForLoops();
10196 return nullptr;
10197}
10198
10199static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10200 auto OrderedClauses =
10201 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10202 if (OrderedClauses.begin() != OrderedClauses.end())
10203 return (*OrderedClauses.begin())->getNumForLoops();
10204 return nullptr;
10205}
10206
10207static bool checkSimdlenSafelenSpecified(Sema &S,
10208 const ArrayRef<OMPClause *> Clauses) {
10209 const OMPSafelenClause *Safelen = nullptr;
10210 const OMPSimdlenClause *Simdlen = nullptr;
10211
10212 for (const OMPClause *Clause : Clauses) {
10213 if (Clause->getClauseKind() == OMPC_safelen)
10214 Safelen = cast<OMPSafelenClause>(Clause);
10215 else if (Clause->getClauseKind() == OMPC_simdlen)
10216 Simdlen = cast<OMPSimdlenClause>(Clause);
10217 if (Safelen && Simdlen)
10218 break;
10219 }
10220
10221 if (Simdlen && Safelen) {
10222 const Expr *SimdlenLength = Simdlen->getSimdlen();
10223 const Expr *SafelenLength = Safelen->getSafelen();
10224 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10225 SimdlenLength->isInstantiationDependent() ||
10226 SimdlenLength->containsUnexpandedParameterPack())
10227 return false;
10228 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10229 SafelenLength->isInstantiationDependent() ||
10230 SafelenLength->containsUnexpandedParameterPack())
10231 return false;
10232 Expr::EvalResult SimdlenResult, SafelenResult;
10233 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10234 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10235 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10236 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10237 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10238 // If both simdlen and safelen clauses are specified, the value of the
10239 // simdlen parameter must be less than or equal to the value of the safelen
10240 // parameter.
10241 if (SimdlenRes > SafelenRes) {
10242 S.Diag(SimdlenLength->getExprLoc(),
10243 diag::err_omp_wrong_simdlen_safelen_values)
10244 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10245 return true;
10246 }
10247 }
10248 return false;
10249}
10250
10251StmtResult
10252Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10253 SourceLocation StartLoc, SourceLocation EndLoc,
10254 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10255 if (!AStmt)
10256 return StmtError();
10257
10258 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", 10258, __extension__ __PRETTY_FUNCTION__
))
;
10259 OMPLoopBasedDirective::HelperExprs B;
10260 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10261 // define the nested loops number.
10262 unsigned NestedLoopCount = checkOpenMPLoop(
10263 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10264 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10265 if (NestedLoopCount == 0)
10266 return StmtError();
10267
10268 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", 10269, __extension__ __PRETTY_FUNCTION__
))
10269 "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", 10269, __extension__ __PRETTY_FUNCTION__
))
;
10270
10271 if (!CurContext->isDependentContext()) {
10272 // Finalize the clauses that need pre-built expressions for CodeGen.
10273 for (OMPClause *C : Clauses) {
10274 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10275 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10276 B.NumIterations, *this, CurScope,
10277 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10278 return StmtError();
10279 }
10280 }
10281
10282 if (checkSimdlenSafelenSpecified(*this, Clauses))
10283 return StmtError();
10284
10285 setFunctionHasBranchProtectedScope();
10286 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10287 Clauses, AStmt, B);
10288}
10289
10290StmtResult
10291Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10292 SourceLocation StartLoc, SourceLocation EndLoc,
10293 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10294 if (!AStmt)
10295 return StmtError();
10296
10297 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", 10297, __extension__ __PRETTY_FUNCTION__
))
;
10298 OMPLoopBasedDirective::HelperExprs B;
10299 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10300 // define the nested loops number.
10301 unsigned NestedLoopCount = checkOpenMPLoop(
10302 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10303 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10304 if (NestedLoopCount == 0)
10305 return StmtError();
10306
10307 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", 10308, __extension__ __PRETTY_FUNCTION__
))
10308 "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", 10308, __extension__ __PRETTY_FUNCTION__
))
;
10309
10310 if (!CurContext->isDependentContext()) {
10311 // Finalize the clauses that need pre-built expressions for CodeGen.
10312 for (OMPClause *C : Clauses) {
10313 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10314 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10315 B.NumIterations, *this, CurScope,
10316 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10317 return StmtError();
10318 }
10319 }
10320
10321 setFunctionHasBranchProtectedScope();
10322 return OMPForDirective::Create(
10323 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10324 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10325}
10326
10327StmtResult Sema::ActOnOpenMPForSimdDirective(
10328 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10329 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10330 if (!AStmt)
10331 return StmtError();
10332
10333 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", 10333, __extension__ __PRETTY_FUNCTION__
))
;
10334 OMPLoopBasedDirective::HelperExprs B;
10335 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10336 // define the nested loops number.
10337 unsigned NestedLoopCount =
10338 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10339 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10340 VarsWithImplicitDSA, B);
10341 if (NestedLoopCount == 0)
10342 return StmtError();
10343
10344 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", 10345, __extension__ __PRETTY_FUNCTION__
))
10345 "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", 10345, __extension__ __PRETTY_FUNCTION__
))
;
10346
10347 if (!CurContext->isDependentContext()) {
10348 // Finalize the clauses that need pre-built expressions for CodeGen.
10349 for (OMPClause *C : Clauses) {
10350 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10351 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10352 B.NumIterations, *this, CurScope,
10353 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10354 return StmtError();
10355 }
10356 }
10357
10358 if (checkSimdlenSafelenSpecified(*this, Clauses))
10359 return StmtError();
10360
10361 setFunctionHasBranchProtectedScope();
10362 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10363 Clauses, AStmt, B);
10364}
10365
10366StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10367 Stmt *AStmt,
10368 SourceLocation StartLoc,
10369 SourceLocation EndLoc) {
10370 if (!AStmt)
10371 return StmtError();
10372
10373 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", 10373, __extension__ __PRETTY_FUNCTION__
))
;
10374 auto BaseStmt = AStmt;
10375 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10376 BaseStmt = CS->getCapturedStmt();
10377 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10378 auto S = C->children();
10379 if (S.begin() == S.end())
10380 return StmtError();
10381 // All associated statements must be '#pragma omp section' except for
10382 // the first one.
10383 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10384 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10385 if (SectionStmt)
10386 Diag(SectionStmt->getBeginLoc(),
10387 diag::err_omp_sections_substmt_not_section);
10388 return StmtError();
10389 }
10390 cast<OMPSectionDirective>(SectionStmt)
10391 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10392 }
10393 } else {
10394 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10395 return StmtError();
10396 }
10397
10398 setFunctionHasBranchProtectedScope();
10399
10400 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10401 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
10402 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10403}
10404
10405StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10406 SourceLocation StartLoc,
10407 SourceLocation EndLoc) {
10408 if (!AStmt)
10409 return StmtError();
10410
10411 setFunctionHasBranchProtectedScope();
10412 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10413
10414 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10415 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10416}
10417
10418static Expr *getDirectCallExpr(Expr *E) {
10419 E = E->IgnoreParenCasts()->IgnoreImplicit();
10420 if (auto *CE = dyn_cast<CallExpr>(E))
10421 if (CE->getDirectCallee())
10422 return E;
10423 return nullptr;
10424}
10425
10426StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10427 Stmt *AStmt,
10428 SourceLocation StartLoc,
10429 SourceLocation EndLoc) {
10430 if (!AStmt)
10431 return StmtError();
10432
10433 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10434
10435 // 5.1 OpenMP
10436 // expression-stmt : an expression statement with one of the following forms:
10437 // expression = target-call ( [expression-list] );
10438 // target-call ( [expression-list] );
10439
10440 SourceLocation TargetCallLoc;
10441
10442 if (!CurContext->isDependentContext()) {
10443 Expr *TargetCall = nullptr;
10444
10445 auto *E = dyn_cast<Expr>(S);
10446 if (!E) {
10447 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10448 return StmtError();
10449 }
10450
10451 E = E->IgnoreParenCasts()->IgnoreImplicit();
10452
10453 if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10454 if (BO->getOpcode() == BO_Assign)
10455 TargetCall = getDirectCallExpr(BO->getRHS());
10456 } else {
10457 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10458 if (COCE->getOperator() == OO_Equal)
10459 TargetCall = getDirectCallExpr(COCE->getArg(1));
10460 if (!TargetCall)
10461 TargetCall = getDirectCallExpr(E);
10462 }
10463 if (!TargetCall) {
10464 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10465 return StmtError();
10466 }
10467 TargetCallLoc = TargetCall->getExprLoc();
10468 }
10469
10470 setFunctionHasBranchProtectedScope();
10471
10472 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10473 TargetCallLoc);
10474}
10475
10476static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10477 OpenMPDirectiveKind K,
10478 DSAStackTy *Stack) {
10479 bool ErrorFound = false;
10480 for (OMPClause *C : Clauses) {
10481 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10482 for (Expr *RefExpr : LPC->varlists()) {
10483 SourceLocation ELoc;
10484 SourceRange ERange;
10485 Expr *SimpleRefExpr = RefExpr;
10486 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10487 if (ValueDecl *D = Res.first) {
10488 auto &&Info = Stack->isLoopControlVariable(D);
10489 if (!Info.first) {
10490 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10491 << getOpenMPDirectiveName(K);
10492 ErrorFound = true;
10493 }
10494 }
10495 }
10496 }
10497 }
10498 return ErrorFound;
10499}
10500
10501StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10502 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10503 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10504 if (!AStmt)
10505 return StmtError();
10506
10507 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10508 // A list item may not appear in a lastprivate clause unless it is the
10509 // loop iteration variable of a loop that is associated with the construct.
10510 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10511 return StmtError();
10512
10513 auto *CS = cast<CapturedStmt>(AStmt);
10514 // 1.2.2 OpenMP Language Terminology
10515 // Structured block - An executable statement with a single entry at the
10516 // top and a single exit at the bottom.
10517 // The point of exit cannot be a branch out of the structured block.
10518 // longjmp() and throw() must not violate the entry/exit criteria.
10519 CS->getCapturedDecl()->setNothrow();
10520
10521 OMPLoopDirective::HelperExprs B;
10522 // In presence of clause 'collapse', it will define the nested loops number.
10523 unsigned NestedLoopCount = checkOpenMPLoop(
10524 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10525 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10526 if (NestedLoopCount == 0)
10527 return StmtError();
10528
10529 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", 10530, __extension__ __PRETTY_FUNCTION__
))
10530 "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", 10530, __extension__ __PRETTY_FUNCTION__
))
;
10531
10532 setFunctionHasBranchProtectedScope();
10533 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10534 NestedLoopCount, Clauses, AStmt, B);
10535}
10536
10537StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10538 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10539 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10540 if (!AStmt)
10541 return StmtError();
10542
10543 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10544 // A list item may not appear in a lastprivate clause unless it is the
10545 // loop iteration variable of a loop that is associated with the construct.
10546 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10547 return StmtError();
10548
10549 auto *CS = cast<CapturedStmt>(AStmt);
10550 // 1.2.2 OpenMP Language Terminology
10551 // Structured block - An executable statement with a single entry at the
10552 // top and a single exit at the bottom.
10553 // The point of exit cannot be a branch out of the structured block.
10554 // longjmp() and throw() must not violate the entry/exit criteria.
10555 CS->getCapturedDecl()->setNothrow();
10556 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10557 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10558 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10559 // 1.2.2 OpenMP Language Terminology
10560 // Structured block - An executable statement with a single entry at the
10561 // top and a single exit at the bottom.
10562 // The point of exit cannot be a branch out of the structured block.
10563 // longjmp() and throw() must not violate the entry/exit criteria.
10564 CS->getCapturedDecl()->setNothrow();
10565 }
10566
10567 OMPLoopDirective::HelperExprs B;
10568 // In presence of clause 'collapse', it will define the nested loops number.
10569 unsigned NestedLoopCount =
10570 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10571 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10572 VarsWithImplicitDSA, B);
10573 if (NestedLoopCount == 0)
10574 return StmtError();
10575
10576 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", 10577, __extension__ __PRETTY_FUNCTION__
))
10577 "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", 10577, __extension__ __PRETTY_FUNCTION__
))
;
10578
10579 setFunctionHasBranchProtectedScope();
10580 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10581
10582 return OMPTeamsGenericLoopDirective::Create(
10583 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10584}
10585
10586StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10587 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10588 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10589 if (!AStmt)
10590 return StmtError();
10591
10592 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10593 // A list item may not appear in a lastprivate clause unless it is the
10594 // loop iteration variable of a loop that is associated with the construct.
10595 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10596 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10597 return StmtError();
10598
10599 auto *CS = cast<CapturedStmt>(AStmt);
10600 // 1.2.2 OpenMP Language Terminology
10601 // Structured block - An executable statement with a single entry at the
10602 // top and a single exit at the bottom.
10603 // The point of exit cannot be a branch out of the structured block.
10604 // longjmp() and throw() must not violate the entry/exit criteria.
10605 CS->getCapturedDecl()->setNothrow();
10606 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10607 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10608 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10609 // 1.2.2 OpenMP Language Terminology
10610 // Structured block - An executable statement with a single entry at the
10611 // top and a single exit at the bottom.
10612 // The point of exit cannot be a branch out of the structured block.
10613 // longjmp() and throw() must not violate the entry/exit criteria.
10614 CS->getCapturedDecl()->setNothrow();
10615 }
10616
10617 OMPLoopDirective::HelperExprs B;
10618 // In presence of clause 'collapse', it will define the nested loops number.
10619 unsigned NestedLoopCount =
10620 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10621 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10622 VarsWithImplicitDSA, B);
10623 if (NestedLoopCount == 0)
10624 return StmtError();
10625
10626 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", 10627, __extension__ __PRETTY_FUNCTION__
))
10627 "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", 10627, __extension__ __PRETTY_FUNCTION__
))
;
10628
10629 setFunctionHasBranchProtectedScope();
10630
10631 return OMPTargetTeamsGenericLoopDirective::Create(
10632 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10633}
10634
10635StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10636 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10637 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10638 if (!AStmt)
10639 return StmtError();
10640
10641 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10642 // A list item may not appear in a lastprivate clause unless it is the
10643 // loop iteration variable of a loop that is associated with the construct.
10644 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10645 return StmtError();
10646
10647 auto *CS = cast<CapturedStmt>(AStmt);
10648 // 1.2.2 OpenMP Language Terminology
10649 // Structured block - An executable statement with a single entry at the
10650 // top and a single exit at the bottom.
10651 // The point of exit cannot be a branch out of the structured block.
10652 // longjmp() and throw() must not violate the entry/exit criteria.
10653 CS->getCapturedDecl()->setNothrow();
10654 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10655 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10656 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10657 // 1.2.2 OpenMP Language Terminology
10658 // Structured block - An executable statement with a single entry at the
10659 // top and a single exit at the bottom.
10660 // The point of exit cannot be a branch out of the structured block.
10661 // longjmp() and throw() must not violate the entry/exit criteria.
10662 CS->getCapturedDecl()->setNothrow();
10663 }
10664
10665 OMPLoopDirective::HelperExprs B;
10666 // In presence of clause 'collapse', it will define the nested loops number.
10667 unsigned NestedLoopCount =
10668 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10669 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10670 VarsWithImplicitDSA, B);
10671 if (NestedLoopCount == 0)
10672 return StmtError();
10673
10674 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", 10675, __extension__ __PRETTY_FUNCTION__
))
10675 "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", 10675, __extension__ __PRETTY_FUNCTION__
))
;
10676
10677 setFunctionHasBranchProtectedScope();
10678
10679 return OMPParallelGenericLoopDirective::Create(
10680 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10681}
10682
10683StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10684 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10685 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10686 if (!AStmt)
10687 return StmtError();
10688
10689 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10690 // A list item may not appear in a lastprivate clause unless it is the
10691 // loop iteration variable of a loop that is associated with the construct.
10692 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10693 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10694 return StmtError();
10695
10696 auto *CS = cast<CapturedStmt>(AStmt);
10697 // 1.2.2 OpenMP Language Terminology
10698 // Structured block - An executable statement with a single entry at the
10699 // top and a single exit at the bottom.
10700 // The point of exit cannot be a branch out of the structured block.
10701 // longjmp() and throw() must not violate the entry/exit criteria.
10702 CS->getCapturedDecl()->setNothrow();
10703 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10704 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10705 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10706 // 1.2.2 OpenMP Language Terminology
10707 // Structured block - An executable statement with a single entry at the
10708 // top and a single exit at the bottom.
10709 // The point of exit cannot be a branch out of the structured block.
10710 // longjmp() and throw() must not violate the entry/exit criteria.
10711 CS->getCapturedDecl()->setNothrow();
10712 }
10713
10714 OMPLoopDirective::HelperExprs B;
10715 // In presence of clause 'collapse', it will define the nested loops number.
10716 unsigned NestedLoopCount =
10717 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10718 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10719 VarsWithImplicitDSA, B);
10720 if (NestedLoopCount == 0)
10721 return StmtError();
10722
10723 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", 10724, __extension__ __PRETTY_FUNCTION__
))
10724 "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", 10724, __extension__ __PRETTY_FUNCTION__
))
;
10725
10726 setFunctionHasBranchProtectedScope();
10727
10728 return OMPTargetParallelGenericLoopDirective::Create(
10729 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10730}
10731
10732StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10733 Stmt *AStmt,
10734 SourceLocation StartLoc,
10735 SourceLocation EndLoc) {
10736 if (!AStmt)
10737 return StmtError();
10738
10739 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", 10739, __extension__ __PRETTY_FUNCTION__
))
;
10740
10741 setFunctionHasBranchProtectedScope();
10742
10743 // OpenMP [2.7.3, single Construct, Restrictions]
10744 // The copyprivate clause must not be used with the nowait clause.
10745 const OMPClause *Nowait = nullptr;
10746 const OMPClause *Copyprivate = nullptr;
10747 for (const OMPClause *Clause : Clauses) {
10748 if (Clause->getClauseKind() == OMPC_nowait)
10749 Nowait = Clause;
10750 else if (Clause->getClauseKind() == OMPC_copyprivate)
10751 Copyprivate = Clause;
10752 if (Copyprivate && Nowait) {
10753 Diag(Copyprivate->getBeginLoc(),
10754 diag::err_omp_single_copyprivate_with_nowait);
10755 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10756 return StmtError();
10757 }
10758 }
10759
10760 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10761}
10762
10763StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
10764 SourceLocation StartLoc,
10765 SourceLocation EndLoc) {
10766 if (!AStmt)
10767 return StmtError();
10768
10769 setFunctionHasBranchProtectedScope();
10770
10771 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10772}
10773
10774StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10775 Stmt *AStmt,
10776 SourceLocation StartLoc,
10777 SourceLocation EndLoc) {
10778 if (!AStmt)
10779 return StmtError();
10780
10781 setFunctionHasBranchProtectedScope();
10782
10783 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10784}
10785
10786StmtResult Sema::ActOnOpenMPCriticalDirective(
10787 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10788 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10789 if (!AStmt)
10790 return StmtError();
10791
10792 bool ErrorFound = false;
10793 llvm::APSInt Hint;
10794 SourceLocation HintLoc;
10795 bool DependentHint = false;
10796 for (const OMPClause *C : Clauses) {
10797 if (C->getClauseKind() == OMPC_hint) {
10798 if (!DirName.getName()) {
10799 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10800 ErrorFound = true;
10801 }
10802 Expr *E = cast<OMPHintClause>(C)->getHint();
10803 if (E->isTypeDependent() || E->isValueDependent() ||
10804 E->isInstantiationDependent()) {
10805 DependentHint = true;
10806 } else {
10807 Hint = E->EvaluateKnownConstInt(Context);
10808 HintLoc = C->getBeginLoc();
10809 }
10810 }
10811 }
10812 if (ErrorFound)
10813 return StmtError();
10814 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
10815 if (Pair.first && DirName.getName() && !DependentHint) {
10816 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10817 Diag(StartLoc, diag::err_omp_critical_with_hint);
10818 if (HintLoc.isValid())
10819 Diag(HintLoc, diag::note_omp_critical_hint_here)
10820 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10821 else
10822 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10823 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10824 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10825 << 1
10826 << toString(C->getHint()->EvaluateKnownConstInt(Context),
10827 /*Radix=*/10, /*Signed=*/false);
10828 } else {
10829 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10830 }
10831 }
10832 }
10833
10834 setFunctionHasBranchProtectedScope();
10835
10836 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10837 Clauses, AStmt);
10838 if (!Pair.first && DirName.getName() && !DependentHint)
10839 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
10840 return Dir;
10841}
10842
10843StmtResult Sema::ActOnOpenMPParallelForDirective(
10844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10845 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10846 if (!AStmt)
10847 return StmtError();
10848
10849 auto *CS = cast<CapturedStmt>(AStmt);
10850 // 1.2.2 OpenMP Language Terminology
10851 // Structured block - An executable statement with a single entry at the
10852 // top and a single exit at the bottom.
10853 // The point of exit cannot be a branch out of the structured block.
10854 // longjmp() and throw() must not violate the entry/exit criteria.
10855 CS->getCapturedDecl()->setNothrow();
10856
10857 OMPLoopBasedDirective::HelperExprs B;
10858 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10859 // define the nested loops number.
10860 unsigned NestedLoopCount =
10861 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10862 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10863 VarsWithImplicitDSA, B);
10864 if (NestedLoopCount == 0)
10865 return StmtError();
10866
10867 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", 10868, __extension__ __PRETTY_FUNCTION__
))
10868 "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", 10868, __extension__ __PRETTY_FUNCTION__
))
;
10869
10870 if (!CurContext->isDependentContext()) {
10871 // Finalize the clauses that need pre-built expressions for CodeGen.
10872 for (OMPClause *C : Clauses) {
10873 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10874 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10875 B.NumIterations, *this, CurScope,
10876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10877 return StmtError();
10878 }
10879 }
10880
10881 setFunctionHasBranchProtectedScope();
10882 return OMPParallelForDirective::Create(
10883 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10884 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10885}
10886
10887StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10888 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10889 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10890 if (!AStmt)
10891 return StmtError();
10892
10893 auto *CS = cast<CapturedStmt>(AStmt);
10894 // 1.2.2 OpenMP Language Terminology
10895 // Structured block - An executable statement with a single entry at the
10896 // top and a single exit at the bottom.
10897 // The point of exit cannot be a branch out of the structured block.
10898 // longjmp() and throw() must not violate the entry/exit criteria.
10899 CS->getCapturedDecl()->setNothrow();
10900
10901 OMPLoopBasedDirective::HelperExprs B;
10902 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10903 // define the nested loops number.
10904 unsigned NestedLoopCount =
10905 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10906 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10907 VarsWithImplicitDSA, B);
10908 if (NestedLoopCount == 0)
10909 return StmtError();
10910
10911 if (!CurContext->isDependentContext()) {
10912 // Finalize the clauses that need pre-built expressions for CodeGen.
10913 for (OMPClause *C : Clauses) {
10914 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10915 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10916 B.NumIterations, *this, CurScope,
10917 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10918 return StmtError();
10919 }
10920 }
10921
10922 if (checkSimdlenSafelenSpecified(*this, Clauses))
10923 return StmtError();
10924
10925 setFunctionHasBranchProtectedScope();
10926 return OMPParallelForSimdDirective::Create(
10927 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10928}
10929
10930StmtResult
10931Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10932 Stmt *AStmt, SourceLocation StartLoc,
10933 SourceLocation EndLoc) {
10934 if (!AStmt)
10935 return StmtError();
10936
10937 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", 10937, __extension__ __PRETTY_FUNCTION__
))
;
10938 auto *CS = cast<CapturedStmt>(AStmt);
10939 // 1.2.2 OpenMP Language Terminology
10940 // Structured block - An executable statement with a single entry at the
10941 // top and a single exit at the bottom.
10942 // The point of exit cannot be a branch out of the structured block.
10943 // longjmp() and throw() must not violate the entry/exit criteria.
10944 CS->getCapturedDecl()->setNothrow();
10945
10946 setFunctionHasBranchProtectedScope();
10947
10948 return OMPParallelMasterDirective::Create(
10949 Context, StartLoc, EndLoc, Clauses, AStmt,
10950 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10951}
10952
10953StmtResult
10954Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
10955 Stmt *AStmt, SourceLocation StartLoc,
10956 SourceLocation EndLoc) {
10957 if (!AStmt)
10958 return StmtError();
10959
10960 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", 10960, __extension__ __PRETTY_FUNCTION__
))
;
10961 auto *CS = cast<CapturedStmt>(AStmt);
10962 // 1.2.2 OpenMP Language Terminology
10963 // Structured block - An executable statement with a single entry at the
10964 // top and a single exit at the bottom.
10965 // The point of exit cannot be a branch out of the structured block.
10966 // longjmp() and throw() must not violate the entry/exit criteria.
10967 CS->getCapturedDecl()->setNothrow();
10968
10969 setFunctionHasBranchProtectedScope();
10970
10971 return OMPParallelMaskedDirective::Create(
10972 Context, StartLoc, EndLoc, Clauses, AStmt,
10973 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
10974}
10975
10976StmtResult
10977Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10978 Stmt *AStmt, SourceLocation StartLoc,
10979 SourceLocation EndLoc) {
10980 if (!AStmt)
10981 return StmtError();
10982
10983 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", 10983, __extension__ __PRETTY_FUNCTION__
))
;
10984 auto BaseStmt = AStmt;
10985 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10986 BaseStmt = CS->getCapturedStmt();
10987 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10988 auto S = C->children();
10989 if (S.begin() == S.end())
10990 return StmtError();
10991 // All associated statements must be '#pragma omp section' except for
10992 // the first one.
10993 for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10994 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10995 if (SectionStmt)
10996 Diag(SectionStmt->getBeginLoc(),
10997 diag::err_omp_parallel_sections_substmt_not_section);
10998 return StmtError();
10999 }
11000 cast<OMPSectionDirective>(SectionStmt)
11001 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11002 }
11003 } else {
11004 Diag(AStmt->getBeginLoc(),
11005 diag::err_omp_parallel_sections_not_compound_stmt);
11006 return StmtError();
11007 }
11008
11009 setFunctionHasBranchProtectedScope();
11010
11011 return OMPParallelSectionsDirective::Create(
11012 Context, StartLoc, EndLoc, Clauses, AStmt,
11013 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11014}
11015
11016/// Find and diagnose mutually exclusive clause kinds.
11017static bool checkMutuallyExclusiveClauses(
11018 Sema &S, ArrayRef<OMPClause *> Clauses,
11019 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11020 const OMPClause *PrevClause = nullptr;
11021 bool ErrorFound = false;
11022 for (const OMPClause *C : Clauses) {
11023 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11024 if (!PrevClause) {
11025 PrevClause = C;
11026 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11027 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11028 << getOpenMPClauseName(C->getClauseKind())
11029 << getOpenMPClauseName(PrevClause->getClauseKind());
11030 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11031 << getOpenMPClauseName(PrevClause->getClauseKind());
11032 ErrorFound = true;
11033 }
11034 }
11035 }
11036 return ErrorFound;
11037}
11038
11039StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11040 Stmt *AStmt, SourceLocation StartLoc,
11041 SourceLocation EndLoc) {
11042 if (!AStmt)
11043 return StmtError();
11044
11045 // OpenMP 5.0, 2.10.1 task Construct
11046 // If a detach clause appears on the directive, then a mergeable clause cannot
11047 // appear on the same directive.
11048 if (checkMutuallyExclusiveClauses(*this, Clauses,
11049 {OMPC_detach, OMPC_mergeable}))
11050 return StmtError();
11051
11052 auto *CS = cast<CapturedStmt>(AStmt);
11053 // 1.2.2 OpenMP Language Terminology
11054 // Structured block - An executable statement with a single entry at the
11055 // top and a single exit at the bottom.
11056 // The point of exit cannot be a branch out of the structured block.
11057 // longjmp() and throw() must not violate the entry/exit criteria.
11058 CS->getCapturedDecl()->setNothrow();
11059
11060 setFunctionHasBranchProtectedScope();
11061
11062 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11063 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11064}
11065
11066StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11067 SourceLocation EndLoc) {
11068 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11069}
11070
11071StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11072 SourceLocation EndLoc) {
11073 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11074}
11075
11076StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11077 SourceLocation StartLoc,
11078 SourceLocation EndLoc,
11079 bool InExContext) {
11080 const OMPAtClause *AtC =
11081 OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11082
11083 if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11084 Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11085 return StmtError();
11086 }
11087
11088 const OMPSeverityClause *SeverityC =
11089 OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11090 const OMPMessageClause *MessageC =
11091 OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11092 Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11093
11094 if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11095 if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11096 Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11097 << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11098 else
11099 Diag(StartLoc, diag::err_diagnose_if_succeeded)
11100 << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11101 if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11102 return StmtError();
11103 }
11104 return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11105}
11106
11107StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11108 SourceLocation StartLoc,
11109 SourceLocation EndLoc) {
11110 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11111}
11112
11113StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11114 Stmt *AStmt,
11115 SourceLocation StartLoc,
11116 SourceLocation EndLoc) {
11117 if (!AStmt)
11118 return StmtError();
11119
11120 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", 11120, __extension__ __PRETTY_FUNCTION__
))
;
11121
11122 setFunctionHasBranchProtectedScope();
11123
11124 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11125 AStmt,
11126 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
11127}
11128
11129StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11130 SourceLocation StartLoc,
11131 SourceLocation EndLoc) {
11132 OMPFlushClause *FC = nullptr;
11133 OMPClause *OrderClause = nullptr;
11134 for (OMPClause *C : Clauses) {
11135 if (C->getClauseKind() == OMPC_flush)
11136 FC = cast<OMPFlushClause>(C);
11137 else
11138 OrderClause = C;
11139 }
11140 OpenMPClauseKind MemOrderKind = OMPC_unknown;
11141 SourceLocation MemOrderLoc;
11142 for (const OMPClause *C : Clauses) {
11143 if (C->getClauseKind() == OMPC_acq_rel ||
11144 C->getClauseKind() == OMPC_acquire ||
11145 C->getClauseKind() == OMPC_release) {
11146 if (MemOrderKind != OMPC_unknown) {
11147 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11148 << getOpenMPDirectiveName(OMPD_flush) << 1
11149 << SourceRange(C->getBeginLoc(), C->getEndLoc());
11150 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11151 << getOpenMPClauseName(MemOrderKind);
11152 } else {
11153 MemOrderKind = C->getClauseKind();
11154 MemOrderLoc = C->getBeginLoc();
11155 }
11156 }
11157 }
11158 if (FC && OrderClause) {
11159 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11160 << getOpenMPClauseName(OrderClause->getClauseKind());
11161 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11162 << getOpenMPClauseName(OrderClause->getClauseKind());
11163 return StmtError();
11164 }
11165 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11166}
11167
11168StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11169 SourceLocation StartLoc,
11170 SourceLocation EndLoc) {
11171 if (Clauses.empty()) {
11172 Diag(StartLoc, diag::err_omp_depobj_expected);
11173 return StmtError();
11174 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11175 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11176 return StmtError();
11177 }
11178 // Only depobj expression and another single clause is allowed.
11179 if (Clauses.size() > 2) {
11180 Diag(Clauses[2]->getBeginLoc(),
11181 diag::err_omp_depobj_single_clause_expected);
11182 return StmtError();
11183 } else if (Clauses.size() < 1) {
11184 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11185 return StmtError();
11186 }
11187 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11188}
11189
11190StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11191 SourceLocation StartLoc,
11192 SourceLocation EndLoc) {
11193 // Check that exactly one clause is specified.
11194 if (Clauses.size() != 1) {
11195 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11196 diag::err_omp_scan_single_clause_expected);
11197 return StmtError();
11198 }
11199 // Check that scan directive is used in the scopeof the OpenMP loop body.
11200 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
11201 Scope *ParentS = S->getParent();
11202 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11203 !ParentS->getBreakParent()->isOpenMPLoopScope())
11204 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11205 << getOpenMPDirectiveName(OMPD_scan) << 5);
11206 }
11207 // Check that only one instance of scan directives is used in the same outer
11208 // region.
11209 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
11210 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11211 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
11212 diag::note_omp_previous_directive)
11213 << "scan";
11214 return StmtError();
11215 }
11216 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
11217 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11218}
11219
11220StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11221 Stmt *AStmt,
11222 SourceLocation StartLoc,
11223 SourceLocation EndLoc) {
11224 const OMPClause *DependFound = nullptr;
11225 const OMPClause *DependSourceClause = nullptr;
11226 const OMPClause *DependSinkClause = nullptr;
11227 bool ErrorFound = false;
11228 const OMPThreadsClause *TC = nullptr;
11229 const OMPSIMDClause *SC = nullptr;
11230 for (const OMPClause *C : Clauses) {
11231 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
11232 DependFound = C;
11233 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
11234 if (DependSourceClause) {
11235 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11236 << getOpenMPDirectiveName(OMPD_ordered)
11237 << getOpenMPClauseName(OMPC_depend) << 2;
11238 ErrorFound = true;
11239 } else {
11240 DependSourceClause = C;
11241 }
11242 if (DependSinkClause) {
11243 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11244 << 0;
11245 ErrorFound = true;
11246 }
11247 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
11248 if (DependSourceClause) {
11249 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
11250 << 1;
11251 ErrorFound = true;
11252 }
11253 DependSinkClause = C;
11254 }
11255 } else if (C->getClauseKind() == OMPC_threads) {
11256 TC = cast<OMPThreadsClause>(C);
11257 } else if (C->getClauseKind() == OMPC_simd) {
11258 SC = cast<OMPSIMDClause>(C);
11259 }
11260 }
11261 if (!ErrorFound && !SC &&
11262 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
11263 // OpenMP [2.8.1,simd Construct, Restrictions]
11264 // An ordered construct with the simd clause is the only OpenMP construct
11265 // that can appear in the simd region.
11266 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11267 << (LangOpts.OpenMP >= 50 ? 1 : 0);
11268 ErrorFound = true;
11269 } else if (DependFound && (TC || SC)) {
11270 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
11271 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11272 ErrorFound = true;
11273 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
11274 Diag(DependFound->getBeginLoc(),
11275 diag::err_omp_ordered_directive_without_param);
11276 ErrorFound = true;
11277 } else if (TC || Clauses.empty()) {
11278 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
11279 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11280 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11281 << (TC != nullptr);
11282 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11283 ErrorFound = true;
11284 }
11285 }
11286 if ((!AStmt && !DependFound) || ErrorFound)
11287 return StmtError();
11288
11289 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11290 // During execution of an iteration of a worksharing-loop or a loop nest
11291 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11292 // must not execute more than one ordered region corresponding to an ordered
11293 // construct without a depend clause.
11294 if (!DependFound) {
11295 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
11296 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11297 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
11298 diag::note_omp_previous_directive)
11299 << "ordered";
11300 return StmtError();
11301 }
11302 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
11303 }
11304
11305 if (AStmt) {
11306 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", 11306, __extension__ __PRETTY_FUNCTION__
))
;
11307
11308 setFunctionHasBranchProtectedScope();
11309 }
11310
11311 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11312}
11313
11314namespace {
11315/// Helper class for checking expression in 'omp atomic [update]'
11316/// construct.
11317class OpenMPAtomicUpdateChecker {
11318 /// Error results for atomic update expressions.
11319 enum ExprAnalysisErrorCode {
11320 /// A statement is not an expression statement.
11321 NotAnExpression,
11322 /// Expression is not builtin binary or unary operation.
11323 NotABinaryOrUnaryExpression,
11324 /// Unary operation is not post-/pre- increment/decrement operation.
11325 NotAnUnaryIncDecExpression,
11326 /// An expression is not of scalar type.
11327 NotAScalarType,
11328 /// A binary operation is not an assignment operation.
11329 NotAnAssignmentOp,
11330 /// RHS part of the binary operation is not a binary expression.
11331 NotABinaryExpression,
11332 /// RHS part is not additive/multiplicative/shift/biwise binary
11333 /// expression.
11334 NotABinaryOperator,
11335 /// RHS binary operation does not have reference to the updated LHS
11336 /// part.
11337 NotAnUpdateExpression,
11338 /// No errors is found.
11339 NoError
11340 };
11341 /// Reference to Sema.
11342 Sema &SemaRef;
11343 /// A location for note diagnostics (when error is found).
11344 SourceLocation NoteLoc;
11345 /// 'x' lvalue part of the source atomic expression.
11346 Expr *X;
11347 /// 'expr' rvalue part of the source atomic expression.
11348 Expr *E;
11349 /// Helper expression of the form
11350 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11351 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11352 Expr *UpdateExpr;
11353 /// Is 'x' a LHS in a RHS part of full update expression. It is
11354 /// important for non-associative operations.
11355 bool IsXLHSInRHSPart;
11356 BinaryOperatorKind Op;
11357 SourceLocation OpLoc;
11358 /// true if the source expression is a postfix unary operation, false
11359 /// if it is a prefix unary operation.
11360 bool IsPostfixUpdate;
11361
11362public:
11363 OpenMPAtomicUpdateChecker(Sema &SemaRef)
11364 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11365 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11366 /// Check specified statement that it is suitable for 'atomic update'
11367 /// constructs and extract 'x', 'expr' and Operation from the original
11368 /// expression. If DiagId and NoteId == 0, then only check is performed
11369 /// without error notification.
11370 /// \param DiagId Diagnostic which should be emitted if error is found.
11371 /// \param NoteId Diagnostic note for the main error message.
11372 /// \return true if statement is not an update expression, false otherwise.
11373 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11374 /// Return the 'x' lvalue part of the source atomic expression.
11375 Expr *getX() const { return X; }
11376 /// Return the 'expr' rvalue part of the source atomic expression.
11377 Expr *getExpr() const { return E; }
11378 /// Return the update expression used in calculation of the updated
11379 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11380 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11381 Expr *getUpdateExpr() const { return UpdateExpr; }
11382 /// Return true if 'x' is LHS in RHS part of full update expression,
11383 /// false otherwise.
11384 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11385
11386 /// true if the source expression is a postfix unary operation, false
11387 /// if it is a prefix unary operation.
11388 bool isPostfixUpdate() const { return IsPostfixUpdate; }
11389
11390private:
11391 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11392 unsigned NoteId = 0);
11393};
11394
11395bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11396 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11397 ExprAnalysisErrorCode ErrorFound = NoError;
11398 SourceLocation ErrorLoc, NoteLoc;
11399 SourceRange ErrorRange, NoteRange;
11400 // Allowed constructs are:
11401 // x = x binop expr;
11402 // x = expr binop x;
11403 if (AtomicBinOp->getOpcode() == BO_Assign) {
11404 X = AtomicBinOp->getLHS();
11405 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11406 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11407 if (AtomicInnerBinOp->isMultiplicativeOp() ||
11408 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11409 AtomicInnerBinOp->isBitwiseOp()) {
11410 Op = AtomicInnerBinOp->getOpcode();
11411 OpLoc = AtomicInnerBinOp->getOperatorLoc();
11412 Expr *LHS = AtomicInnerBinOp->getLHS();
11413 Expr *RHS = AtomicInnerBinOp->getRHS();
11414 llvm::FoldingSetNodeID XId, LHSId, RHSId;
11415 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11416 /*Canonical=*/true);
11417 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11418 /*Canonical=*/true);
11419 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11420 /*Canonical=*/true);
11421 if (XId == LHSId) {
11422 E = RHS;
11423 IsXLHSInRHSPart = true;
11424 } else if (XId == RHSId) {
11425 E = LHS;
11426 IsXLHSInRHSPart = false;
11427 } else {
11428 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11429 ErrorRange = AtomicInnerBinOp->getSourceRange();
11430 NoteLoc = X->getExprLoc();
11431 NoteRange = X->getSourceRange();
11432 ErrorFound = NotAnUpdateExpression;
11433 }
11434 } else {
11435 ErrorLoc = AtomicInnerBinOp->getExprLoc();
11436 ErrorRange = AtomicInnerBinOp->getSourceRange();
11437 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11438 NoteRange = SourceRange(NoteLoc, NoteLoc);
11439 ErrorFound = NotABinaryOperator;
11440 }
11441 } else {
11442 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11443 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11444 ErrorFound = NotABinaryExpression;
11445 }
11446 } else {
11447 ErrorLoc = AtomicBinOp->getExprLoc();
11448 ErrorRange = AtomicBinOp->getSourceRange();
11449 NoteLoc = AtomicBinOp->getOperatorLoc();
11450 NoteRange = SourceRange(NoteLoc, NoteLoc);
11451 ErrorFound = NotAnAssignmentOp;
11452 }
11453 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11454 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11455 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11456 return true;
11457 }
11458 if (SemaRef.CurContext->isDependentContext())
11459 E = X = UpdateExpr = nullptr;
11460 return ErrorFound != NoError;
11461}
11462
11463bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11464 unsigned NoteId) {
11465 ExprAnalysisErrorCode ErrorFound = NoError;
11466 SourceLocation ErrorLoc, NoteLoc;
11467 SourceRange ErrorRange, NoteRange;
11468 // Allowed constructs are:
11469 // x++;
11470 // x--;
11471 // ++x;
11472 // --x;
11473 // x binop= expr;
11474 // x = x binop expr;
11475 // x = expr binop x;
11476 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11477 AtomicBody = AtomicBody->IgnoreParenImpCasts();
11478 if (AtomicBody->getType()->isScalarType() ||
11479 AtomicBody->isInstantiationDependent()) {
11480 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11481 AtomicBody->IgnoreParenImpCasts())) {
11482 // Check for Compound Assignment Operation
11483 Op = BinaryOperator::getOpForCompoundAssignment(
11484 AtomicCompAssignOp->getOpcode());
11485 OpLoc = AtomicCompAssignOp->getOperatorLoc();
11486 E = AtomicCompAssignOp->getRHS();
11487 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11488 IsXLHSInRHSPart = true;
11489 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11490 AtomicBody->IgnoreParenImpCasts())) {
11491 // Check for Binary Operation
11492 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11493 return true;
11494 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11495 AtomicBody->IgnoreParenImpCasts())) {
11496 // Check for Unary Operation
11497 if (AtomicUnaryOp->isIncrementDecrementOp()) {
11498 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11499 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11500 OpLoc = AtomicUnaryOp->getOperatorLoc();
11501 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11502 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11503 IsXLHSInRHSPart = true;
11504 } else {
11505 ErrorFound = NotAnUnaryIncDecExpression;
11506 ErrorLoc = AtomicUnaryOp->getExprLoc();
11507 ErrorRange = AtomicUnaryOp->getSourceRange();
11508 NoteLoc = AtomicUnaryOp->getOperatorLoc();
11509 NoteRange = SourceRange(NoteLoc, NoteLoc);
11510 }
11511 } else if (!AtomicBody->isInstantiationDependent()) {
11512 ErrorFound = NotABinaryOrUnaryExpression;
11513 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11514 NoteRange = ErrorRange = AtomicBody->getSourceRange();
11515 }
11516 } else {
11517 ErrorFound = NotAScalarType;
11518 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11519 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11520 }
11521 } else {
11522 ErrorFound = NotAnExpression;
11523 NoteLoc = ErrorLoc = S->getBeginLoc();
11524 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11525 }
11526 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11527 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11528 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11529 return true;
11530 }
11531 if (SemaRef.CurContext->isDependentContext())
11532 E = X = UpdateExpr = nullptr;
11533 if (ErrorFound == NoError && E && X) {
11534 // Build an update expression of form 'OpaqueValueExpr(x) binop
11535 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11536 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11537 auto *OVEX = new (SemaRef.getASTContext())
11538 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11539 auto *OVEExpr = new (SemaRef.getASTContext())
11540 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11541 ExprResult Update =
11542 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11543 IsXLHSInRHSPart ? OVEExpr : OVEX);
11544 if (Update.isInvalid())
11545 return true;
11546 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11547 Sema::AA_Casting);
11548 if (Update.isInvalid())
11549 return true;
11550 UpdateExpr = Update.get();
11551 }
11552 return ErrorFound != NoError;
11553}
11554
11555/// Get the node id of the fixed point of an expression \a S.
11556llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11557 llvm::FoldingSetNodeID Id;
11558 S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11559 return Id;
11560}
11561
11562/// Check if two expressions are same.
11563bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11564 const Expr *RHS) {
11565 return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11566}
11567
11568class OpenMPAtomicCompareChecker {
11569public:
11570 /// All kinds of errors that can occur in `atomic compare`
11571 enum ErrorTy {
11572 /// Empty compound statement.
11573 NoStmt = 0,
11574 /// More than one statement in a compound statement.
11575 MoreThanOneStmt,
11576 /// Not an assignment binary operator.
11577 NotAnAssignment,
11578 /// Not a conditional operator.
11579 NotCondOp,
11580 /// Wrong false expr. According to the spec, 'x' should be at the false
11581 /// expression of a conditional expression.
11582 WrongFalseExpr,
11583 /// The condition of a conditional expression is not a binary operator.
11584 NotABinaryOp,
11585 /// Invalid binary operator (not <, >, or ==).
11586 InvalidBinaryOp,
11587 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11588 InvalidComparison,
11589 /// X is not a lvalue.
11590 XNotLValue,
11591 /// Not a scalar.
11592 NotScalar,
11593 /// Not an integer.
11594 NotInteger,
11595 /// 'else' statement is not expected.
11596 UnexpectedElse,
11597 /// Not an equality operator.
11598 NotEQ,
11599 /// Invalid assignment (not v == x).
11600 InvalidAssignment,
11601 /// Not if statement
11602 NotIfStmt,
11603 /// More than two statements in a compund statement.
11604 MoreThanTwoStmts,
11605 /// Not a compound statement.
11606 NotCompoundStmt,
11607 /// No else statement.
11608 NoElse,
11609 /// Not 'if (r)'.
11610 InvalidCondition,
11611 /// No error.
11612 NoError,
11613 };
11614
11615 struct ErrorInfoTy {
11616 ErrorTy Error;
11617 SourceLocation ErrorLoc;
11618 SourceRange ErrorRange;
11619 SourceLocation NoteLoc;
11620 SourceRange NoteRange;
11621 };
11622
11623 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11624
11625 /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11626 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11627
11628 Expr *getX() const { return X; }
11629 Expr *getE() const { return E; }
11630 Expr *getD() const { return D; }
11631 Expr *getCond() const { return C; }
11632 bool isXBinopExpr() const { return IsXBinopExpr; }
11633
11634protected:
11635 /// Reference to ASTContext
11636 ASTContext &ContextRef;
11637 /// 'x' lvalue part of the source atomic expression.
11638 Expr *X = nullptr;
11639 /// 'expr' or 'e' rvalue part of the source atomic expression.
11640 Expr *E = nullptr;
11641 /// 'd' rvalue part of the source atomic expression.
11642 Expr *D = nullptr;
11643 /// 'cond' part of the source atomic expression. It is in one of the following
11644 /// forms:
11645 /// expr ordop x
11646 /// x ordop expr
11647 /// x == e
11648 /// e == x
11649 Expr *C = nullptr;
11650 /// True if the cond expr is in the form of 'x ordop expr'.
11651 bool IsXBinopExpr = true;
11652
11653 /// Check if it is a valid conditional update statement (cond-update-stmt).
11654 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11655
11656 /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11657 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11658
11659 /// Check if all captured values have right type.
11660 bool checkType(ErrorInfoTy &ErrorInfo) const;
11661
11662 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11663 bool ShouldBeLValue, bool ShouldBeInteger = false) {
11664 if (E->isInstantiationDependent())
11665 return true;
11666
11667 if (ShouldBeLValue && !E->isLValue()) {
11668 ErrorInfo.Error = ErrorTy::XNotLValue;
11669 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11670 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11671 return false;
11672 }
11673
11674 QualType QTy = E->getType();
11675 if (!QTy->isScalarType()) {
11676 ErrorInfo.Error = ErrorTy::NotScalar;
11677 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11678 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11679 return false;
11680 }
11681 if (ShouldBeInteger && !QTy->isIntegerType()) {
11682 ErrorInfo.Error = ErrorTy::NotInteger;
11683 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11684 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11685 return false;
11686 }
11687
11688 return true;
11689 }
11690 };
11691
11692bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11693 ErrorInfoTy &ErrorInfo) {
11694 auto *Then = S->getThen();
11695 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11696 if (CS->body_empty()) {
11697 ErrorInfo.Error = ErrorTy::NoStmt;
11698 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11699 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11700 return false;
11701 }
11702 if (CS->size() > 1) {
11703 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11704 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11705 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11706 return false;
11707 }
11708 Then = CS->body_front();
11709 }
11710
11711 auto *BO = dyn_cast<BinaryOperator>(Then);
11712 if (!BO) {
11713 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11714 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11715 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11716 return false;
11717 }
11718 if (BO->getOpcode() != BO_Assign) {
11719 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11720 ErrorInfo.ErrorLoc = BO->getExprLoc();
11721 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11722 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11723 return false;
11724 }
11725
11726 X = BO->getLHS();
11727
11728 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11729 if (!Cond) {
11730 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11731 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11732 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11733 return false;
11734 }
11735
11736 switch (Cond->getOpcode()) {
11737 case BO_EQ: {
11738 C = Cond;
11739 D = BO->getRHS();
11740 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11741 E = Cond->getRHS();
11742 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11743 E = Cond->getLHS();
11744 } else {
11745 ErrorInfo.Error = ErrorTy::InvalidComparison;
11746 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11747 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11748 return false;
11749 }
11750 break;
11751 }
11752 case BO_LT:
11753 case BO_GT: {
11754 E = BO->getRHS();
11755 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11756 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11757 C = Cond;
11758 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11759 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11760 C = Cond;
11761 IsXBinopExpr = false;
11762 } else {
11763 ErrorInfo.Error = ErrorTy::InvalidComparison;
11764 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11765 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11766 return false;
11767 }
11768 break;
11769 }
11770 default:
11771 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11772 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11773 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11774 return false;
11775 }
11776
11777 if (S->getElse()) {
11778 ErrorInfo.Error = ErrorTy::UnexpectedElse;
11779 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11780 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11781 return false;
11782 }
11783
11784 return true;
11785}
11786
11787bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11788 ErrorInfoTy &ErrorInfo) {
11789 auto *BO = dyn_cast<BinaryOperator>(S);
11790 if (!BO) {
11791 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11792 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11793 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11794 return false;
11795 }
11796 if (BO->getOpcode() != BO_Assign) {
11797 ErrorInfo.Error = ErrorTy::NotAnAssignment;
11798 ErrorInfo.ErrorLoc = BO->getExprLoc();
11799 ErrorInfo.NoteLoc = BO->getOperatorLoc();
11800 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11801 return false;
11802 }
11803
11804 X = BO->getLHS();
11805
11806 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11807 if (!CO) {
11808 ErrorInfo.Error = ErrorTy::NotCondOp;
11809 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11810 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11811 return false;
11812 }
11813
11814 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11815 ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11816 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11817 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11818 CO->getFalseExpr()->getSourceRange();
11819 return false;
11820 }
11821
11822 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11823 if (!Cond) {
11824 ErrorInfo.Error = ErrorTy::NotABinaryOp;
11825 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11826 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11827 CO->getCond()->getSourceRange();
11828 return false;
11829 }
11830
11831 switch (Cond->getOpcode()) {
11832 case BO_EQ: {
11833 C = Cond;
11834 D = CO->getTrueExpr();
11835 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11836 E = Cond->getRHS();
11837 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11838 E = Cond->getLHS();
11839 } else {
11840 ErrorInfo.Error = ErrorTy::InvalidComparison;
11841 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11842 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11843 return false;
11844 }
11845 break;
11846 }
11847 case BO_LT:
11848 case BO_GT: {
11849 E = CO->getTrueExpr();
11850 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11851 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11852 C = Cond;
11853 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11854 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11855 C = Cond;
11856 IsXBinopExpr = false;
11857 } else {
11858 ErrorInfo.Error = ErrorTy::InvalidComparison;
11859 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11860 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11861 return false;
11862 }
11863 break;
11864 }
11865 default:
11866 ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11867 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11868 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11869 return false;
11870 }
11871
11872 return true;
11873}
11874
11875bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11876 // 'x' and 'e' cannot be nullptr
11877 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", 11877, __extension__ __PRETTY_FUNCTION__
))
;
11878
11879 if (!CheckValue(X, ErrorInfo, true))
11880 return false;
11881
11882 if (!CheckValue(E, ErrorInfo, false))
11883 return false;
11884
11885 if (D && !CheckValue(D, ErrorInfo, false))
11886 return false;
11887
11888 return true;
11889}
11890
11891bool OpenMPAtomicCompareChecker::checkStmt(
11892 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11893 auto *CS = dyn_cast<CompoundStmt>(S);
11894 if (CS) {
11895 if (CS->body_empty()) {
11896 ErrorInfo.Error = ErrorTy::NoStmt;
11897 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11898 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11899 return false;
11900 }
11901
11902 if (CS->size() != 1) {
11903 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11904 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11905 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11906 return false;
11907 }
11908 S = CS->body_front();
11909 }
11910
11911 auto Res = false;
11912
11913 if (auto *IS = dyn_cast<IfStmt>(S)) {
11914 // Check if the statement is in one of the following forms
11915 // (cond-update-stmt):
11916 // if (expr ordop x) { x = expr; }
11917 // if (x ordop expr) { x = expr; }
11918 // if (x == e) { x = d; }
11919 Res = checkCondUpdateStmt(IS, ErrorInfo);
11920 } else {
11921 // Check if the statement is in one of the following forms (cond-expr-stmt):
11922 // x = expr ordop x ? expr : x;
11923 // x = x ordop expr ? expr : x;
11924 // x = x == e ? d : x;
11925 Res = checkCondExprStmt(S, ErrorInfo);
11926 }
11927
11928 if (!Res)
11929 return false;
11930
11931 return checkType(ErrorInfo);
11932}
11933
11934class OpenMPAtomicCompareCaptureChecker final
11935 : public OpenMPAtomicCompareChecker {
11936public:
11937 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11938
11939 Expr *getV() const { return V; }
11940 Expr *getR() const { return R; }
11941 bool isFailOnly() const { return IsFailOnly; }
11942 bool isPostfixUpdate() const { return IsPostfixUpdate; }
11943
11944 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11945 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11946
11947private:
11948 bool checkType(ErrorInfoTy &ErrorInfo);
11949
11950 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11951 // form of 'conditional-update-capture-atomic' structured block on the v5.2
11952 // spec p.p. 82:
11953 // (1) { v = x; cond-update-stmt }
11954 // (2) { cond-update-stmt v = x; }
11955 // (3) if(x == e) { x = d; } else { v = x; }
11956 // (4) { r = x == e; if(r) { x = d; } }
11957 // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11958
11959 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11960 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11961
11962 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11963 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11964 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11965
11966 /// 'v' lvalue part of the source atomic expression.
11967 Expr *V = nullptr;
11968 /// 'r' lvalue part of the source atomic expression.
11969 Expr *R = nullptr;
11970 /// If 'v' is only updated when the comparison fails.
11971 bool IsFailOnly = false;
11972 /// If original value of 'x' must be stored in 'v', not an updated one.
11973 bool IsPostfixUpdate = false;
11974};
11975
11976bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11977 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11978 return false;
11979
11980 if (V && !CheckValue(V, ErrorInfo, true))
11981 return false;
11982
11983 if (R && !CheckValue(R, ErrorInfo, true, true))
11984 return false;
11985
11986 return true;
11987}
11988
11989bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11990 ErrorInfoTy &ErrorInfo) {
11991 IsFailOnly = true;
11992
11993 auto *Then = S->getThen();
11994 if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11995 if (CS->body_empty()) {
11996 ErrorInfo.Error = ErrorTy::NoStmt;
11997 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11998 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11999 return false;
12000 }
12001 if (CS->size() > 1) {
12002 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12003 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12004 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12005 return false;
12006 }
12007 Then = CS->body_front();
12008 }
12009
12010 auto *BO = dyn_cast<BinaryOperator>(Then);
12011 if (!BO) {
12012 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12013 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12014 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12015 return false;
12016 }
12017 if (BO->getOpcode() != BO_Assign) {
12018 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12019 ErrorInfo.ErrorLoc = BO->getExprLoc();
12020 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12021 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12022 return false;
12023 }
12024
12025 X = BO->getLHS();
12026 D = BO->getRHS();
12027
12028 auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12029 if (!Cond) {
12030 ErrorInfo.Error = ErrorTy::NotABinaryOp;
12031 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12032 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12033 return false;
12034 }
12035 if (Cond->getOpcode() != BO_EQ) {
12036 ErrorInfo.Error = ErrorTy::NotEQ;
12037 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12038 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12039 return false;
12040 }
12041
12042 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12043 E = Cond->getRHS();
12044 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12045 E = Cond->getLHS();
12046 } else {
12047 ErrorInfo.Error = ErrorTy::InvalidComparison;
12048 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12049 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12050 return false;
12051 }
12052
12053 C = Cond;
12054
12055 if (!S->getElse()) {
12056 ErrorInfo.Error = ErrorTy::NoElse;
12057 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12058 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12059 return false;
12060 }
12061
12062 auto *Else = S->getElse();
12063 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12064 if (CS->body_empty()) {
12065 ErrorInfo.Error = ErrorTy::NoStmt;
12066 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12067 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12068 return false;
12069 }
12070 if (CS->size() > 1) {
12071 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12072 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12073 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12074 return false;
12075 }
12076 Else = CS->body_front();
12077 }
12078
12079 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12080 if (!ElseBO) {
12081 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12082 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12083 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12084 return false;
12085 }
12086 if (ElseBO->getOpcode() != BO_Assign) {
12087 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12088 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12089 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12090 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12091 return false;
12092 }
12093
12094 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12095 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12096 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12097 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12098 ElseBO->getRHS()->getSourceRange();
12099 return false;
12100 }
12101
12102 V = ElseBO->getLHS();
12103
12104 return checkType(ErrorInfo);
12105}
12106
12107bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12108 ErrorInfoTy &ErrorInfo) {
12109 // We don't check here as they should be already done before call this
12110 // function.
12111 auto *CS = cast<CompoundStmt>(S);
12112 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", 12112, __extension__ __PRETTY_FUNCTION__
))
;
12113 auto *S1 = cast<BinaryOperator>(CS->body_front());
12114 auto *S2 = cast<IfStmt>(CS->body_back());
12115 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", 12115, __extension__ __PRETTY_FUNCTION__
))
;
12116
12117 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12118 ErrorInfo.Error = ErrorTy::InvalidCondition;
12119 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12120 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12121 return false;
12122 }
12123
12124 R = S1->getLHS();
12125
12126 auto *Then = S2->getThen();
12127 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12128 if (ThenCS->body_empty()) {
12129 ErrorInfo.Error = ErrorTy::NoStmt;
12130 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12131 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12132 return false;
12133 }
12134 if (ThenCS->size() > 1) {
12135 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12136 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12137 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12138 return false;
12139 }
12140 Then = ThenCS->body_front();
12141 }
12142
12143 auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12144 if (!ThenBO) {
12145 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12146 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12147 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12148 return false;
12149 }
12150 if (ThenBO->getOpcode() != BO_Assign) {
12151 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12152 ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12153 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12154 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12155 return false;
12156 }
12157
12158 X = ThenBO->getLHS();
12159 D = ThenBO->getRHS();
12160
12161 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12162 if (BO->getOpcode() != BO_EQ) {
12163 ErrorInfo.Error = ErrorTy::NotEQ;
12164 ErrorInfo.ErrorLoc = BO->getExprLoc();
12165 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12166 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12167 return false;
12168 }
12169
12170 C = BO;
12171
12172 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12173 E = BO->getRHS();
12174 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12175 E = BO->getLHS();
12176 } else {
12177 ErrorInfo.Error = ErrorTy::InvalidComparison;
12178 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12179 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12180 return false;
12181 }
12182
12183 if (S2->getElse()) {
12184 IsFailOnly = true;
12185
12186 auto *Else = S2->getElse();
12187 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12188 if (ElseCS->body_empty()) {
12189 ErrorInfo.Error = ErrorTy::NoStmt;
12190 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12191 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12192 return false;
12193 }
12194 if (ElseCS->size() > 1) {
12195 ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12196 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12197 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12198 return false;
12199 }
12200 Else = ElseCS->body_front();
12201 }
12202
12203 auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12204 if (!ElseBO) {
12205 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12206 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12207 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12208 return false;
12209 }
12210 if (ElseBO->getOpcode() != BO_Assign) {
12211 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12212 ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12213 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12214 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12215 return false;
12216 }
12217 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12218 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12219 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12220 ErrorInfo.NoteLoc = X->getExprLoc();
12221 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12222 ErrorInfo.NoteRange = X->getSourceRange();
12223 return false;
12224 }
12225
12226 V = ElseBO->getLHS();
12227 }
12228
12229 return checkType(ErrorInfo);
12230}
12231
12232bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12233 ErrorInfoTy &ErrorInfo) {
12234 // if(x == e) { x = d; } else { v = x; }
12235 if (auto *IS = dyn_cast<IfStmt>(S))
12236 return checkForm3(IS, ErrorInfo);
12237
12238 auto *CS = dyn_cast<CompoundStmt>(S);
12239 if (!CS) {
12240 ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12241 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12242 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12243 return false;
12244 }
12245 if (CS->body_empty()) {
12246 ErrorInfo.Error = ErrorTy::NoStmt;
12247 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12248 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12249 return false;
12250 }
12251
12252 // { if(x == e) { x = d; } else { v = x; } }
12253 if (CS->size() == 1) {
12254 auto *IS = dyn_cast<IfStmt>(CS->body_front());
12255 if (!IS) {
12256 ErrorInfo.Error = ErrorTy::NotIfStmt;
12257 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12258 ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12259 CS->body_front()->getSourceRange();
12260 return false;
12261 }
12262
12263 return checkForm3(IS, ErrorInfo);
12264 } else if (CS->size() == 2) {
12265 auto *S1 = CS->body_front();
12266 auto *S2 = CS->body_back();
12267
12268 Stmt *UpdateStmt = nullptr;
12269 Stmt *CondUpdateStmt = nullptr;
12270 Stmt *CondExprStmt = nullptr;
12271
12272 if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12273 // It could be one of the following cases:
12274 // { v = x; cond-update-stmt }
12275 // { v = x; cond-expr-stmt }
12276 // { cond-expr-stmt; v = x; }
12277 // form 45
12278 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12279 isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12280 // check if form 45
12281 if (isa<IfStmt>(S2))
12282 return checkForm45(CS, ErrorInfo);
12283 // { cond-expr-stmt; v = x; }
12284 CondExprStmt = S1;
12285 UpdateStmt = S2;
12286 } else {
12287 IsPostfixUpdate = true;
12288 UpdateStmt = S1;
12289 if (isa<IfStmt>(S2)) {
12290 // { v = x; cond-update-stmt }
12291 CondUpdateStmt = S2;
12292 } else {
12293 // { v = x; cond-expr-stmt }
12294 CondExprStmt = S2;
12295 }
12296 }
12297 } else {
12298 // { cond-update-stmt v = x; }
12299 UpdateStmt = S2;
12300 CondUpdateStmt = S1;
12301 }
12302
12303 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12304 auto *IS = dyn_cast<IfStmt>(CUS);
12305 if (!IS) {
12306 ErrorInfo.Error = ErrorTy::NotIfStmt;
12307 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12308 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12309 return false;
12310 }
12311
12312 return checkCondUpdateStmt(IS, ErrorInfo);
12313 };
12314
12315 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12316 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12317 auto *BO = dyn_cast<BinaryOperator>(US);
12318 if (!BO) {
12319 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12320 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12321 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12322 return false;
12323 }
12324 if (BO->getOpcode() != BO_Assign) {
12325 ErrorInfo.Error = ErrorTy::NotAnAssignment;
12326 ErrorInfo.ErrorLoc = BO->getExprLoc();
12327 ErrorInfo.NoteLoc = BO->getOperatorLoc();
12328 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12329 return false;
12330 }
12331 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12332 ErrorInfo.Error = ErrorTy::InvalidAssignment;
12333 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12334 ErrorInfo.NoteLoc = this->X->getExprLoc();
12335 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12336 ErrorInfo.NoteRange = this->X->getSourceRange();
12337 return false;
12338 }
12339
12340 this->V = BO->getLHS();
12341
12342 return true;
12343 };
12344
12345 if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12346 return false;
12347 if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12348 return false;
12349 if (!CheckUpdateStmt(UpdateStmt))
12350 return false;
12351 } else {
12352 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12353 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12354 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12355 return false;
12356 }
12357
12358 return checkType(ErrorInfo);
12359}
12360} // namespace
12361
12362StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12363 Stmt *AStmt,
12364 SourceLocation StartLoc,
12365 SourceLocation EndLoc) {
12366 // Register location of the first atomic directive.
12367 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
12368 if (!AStmt)
12369 return StmtError();
12370
12371 // 1.2.2 OpenMP Language Terminology
12372 // Structured block - An executable statement with a single entry at the
12373 // top and a single exit at the bottom.
12374 // The point of exit cannot be a branch out of the structured block.
12375 // longjmp() and throw() must not violate the entry/exit criteria.
12376 OpenMPClauseKind AtomicKind = OMPC_unknown;
12377 SourceLocation AtomicKindLoc;
12378 OpenMPClauseKind MemOrderKind = OMPC_unknown;
12379 SourceLocation MemOrderLoc;
12380 bool MutexClauseEncountered = false;
12381 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12382 for (const OMPClause *C : Clauses) {
12383 switch (C->getClauseKind()) {
12384 case OMPC_read:
12385 case OMPC_write:
12386 case OMPC_update:
12387 MutexClauseEncountered = true;
12388 [[fallthrough]];
12389 case OMPC_capture:
12390 case OMPC_compare: {
12391 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12392 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12393 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12394 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12395 << getOpenMPClauseName(AtomicKind);
12396 } else {
12397 AtomicKind = C->getClauseKind();
12398 AtomicKindLoc = C->getBeginLoc();
12399 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12400 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12401 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12402 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12403 << getOpenMPClauseName(AtomicKind);
12404 }
12405 }
12406 break;
12407 }
12408 case OMPC_seq_cst:
12409 case OMPC_acq_rel:
12410 case OMPC_acquire:
12411 case OMPC_release:
12412 case OMPC_relaxed: {
12413 if (MemOrderKind != OMPC_unknown) {
12414 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12415 << getOpenMPDirectiveName(OMPD_atomic) << 0
12416 << SourceRange(C->getBeginLoc(), C->getEndLoc());
12417 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12418 << getOpenMPClauseName(MemOrderKind);
12419 } else {
12420 MemOrderKind = C->getClauseKind();
12421 MemOrderLoc = C->getBeginLoc();
12422 }
12423 break;
12424 }
12425 // The following clauses are allowed, but we don't need to do anything here.
12426 case OMPC_hint:
12427 break;
12428 default:
12429 llvm_unreachable("unknown clause is encountered")::llvm::llvm_unreachable_internal("unknown clause is encountered"
, "clang/lib/Sema/SemaOpenMP.cpp", 12429)
;
12430 }
12431 }
12432 bool IsCompareCapture = false;
12433 if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12434 EncounteredAtomicKinds.contains(OMPC_capture)) {
12435 IsCompareCapture = true;
12436 AtomicKind = OMPC_compare;
12437 }
12438 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12439 // If atomic-clause is read then memory-order-clause must not be acq_rel or
12440 // release.
12441 // If atomic-clause is write then memory-order-clause must not be acq_rel or
12442 // acquire.
12443 // If atomic-clause is update or not present then memory-order-clause must not
12444 // be acq_rel or acquire.
12445 if ((AtomicKind == OMPC_read &&
12446 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12447 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12448 AtomicKind == OMPC_unknown) &&
12449 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12450 SourceLocation Loc = AtomicKindLoc;
12451 if (AtomicKind == OMPC_unknown)
12452 Loc = StartLoc;
12453 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12454 << getOpenMPClauseName(AtomicKind)
12455 << (AtomicKind == OMPC_unknown ? 1 : 0)
12456 << getOpenMPClauseName(MemOrderKind);
12457 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12458 << getOpenMPClauseName(MemOrderKind);
12459 }
12460
12461 Stmt *Body = AStmt;
12462 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12463 Body = EWC->getSubExpr();
12464
12465 Expr *X = nullptr;
12466 Expr *V = nullptr;
12467 Expr *E = nullptr;
12468 Expr *UE = nullptr;
12469 Expr *D = nullptr;
12470 Expr *CE = nullptr;
12471 Expr *R = nullptr;
12472 bool IsXLHSInRHSPart = false;
12473 bool IsPostfixUpdate = false;
12474 bool IsFailOnly = false;
12475 // OpenMP [2.12.6, atomic Construct]
12476 // In the next expressions:
12477 // * x and v (as applicable) are both l-value expressions with scalar type.
12478 // * During the execution of an atomic region, multiple syntactic
12479 // occurrences of x must designate the same storage location.
12480 // * Neither of v and expr (as applicable) may access the storage location
12481 // designated by x.
12482 // * Neither of x and expr (as applicable) may access the storage location
12483 // designated by v.
12484 // * expr is an expression with scalar type.
12485 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12486 // * binop, binop=, ++, and -- are not overloaded operators.
12487 // * The expression x binop expr must be numerically equivalent to x binop
12488 // (expr). This requirement is satisfied if the operators in expr have
12489 // precedence greater than binop, or by using parentheses around expr or
12490 // subexpressions of expr.
12491 // * The expression expr binop x must be numerically equivalent to (expr)
12492 // binop x. This requirement is satisfied if the operators in expr have
12493 // precedence equal to or greater than binop, or by using parentheses around
12494 // expr or subexpressions of expr.
12495 // * For forms that allow multiple occurrences of x, the number of times
12496 // that x is evaluated is unspecified.
12497 if (AtomicKind == OMPC_read) {
12498 enum {
12499 NotAnExpression,
12500 NotAnAssignmentOp,
12501 NotAScalarType,
12502 NotAnLValue,
12503 NoError
12504 } ErrorFound = NoError;
12505 SourceLocation ErrorLoc, NoteLoc;
12506 SourceRange ErrorRange, NoteRange;
12507 // If clause is read:
12508 // v = x;
12509 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12510 const auto *AtomicBinOp =
12511 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12512 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12513 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12514 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12515 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12516 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12517 if (!X->isLValue() || !V->isLValue()) {
12518 const Expr *NotLValueExpr = X->isLValue() ? V : X;
12519 ErrorFound = NotAnLValue;
12520 ErrorLoc = AtomicBinOp->getExprLoc();
12521 ErrorRange = AtomicBinOp->getSourceRange();
12522 NoteLoc = NotLValueExpr->getExprLoc();
12523 NoteRange = NotLValueExpr->getSourceRange();
12524 }
12525 } else if (!X->isInstantiationDependent() ||
12526 !V->isInstantiationDependent()) {
12527 const Expr *NotScalarExpr =
12528 (X->isInstantiationDependent() || X->getType()->isScalarType())
12529 ? V
12530 : X;
12531 ErrorFound = NotAScalarType;
12532 ErrorLoc = AtomicBinOp->getExprLoc();
12533 ErrorRange = AtomicBinOp->getSourceRange();
12534 NoteLoc = NotScalarExpr->getExprLoc();
12535 NoteRange = NotScalarExpr->getSourceRange();
12536 }
12537 } else if (!AtomicBody->isInstantiationDependent()) {
12538 ErrorFound = NotAnAssignmentOp;
12539 ErrorLoc = AtomicBody->getExprLoc();
12540 ErrorRange = AtomicBody->getSourceRange();
12541 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12542 : AtomicBody->getExprLoc();
12543 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12544 : AtomicBody->getSourceRange();
12545 }
12546 } else {
12547 ErrorFound = NotAnExpression;
12548 NoteLoc = ErrorLoc = Body->getBeginLoc();
12549 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12550 }
12551 if (ErrorFound != NoError) {
12552 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12553 << ErrorRange;
12554 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12555 << ErrorFound << NoteRange;
12556 return StmtError();
12557 }
12558 if (CurContext->isDependentContext())
12559 V = X = nullptr;
12560 } else if (AtomicKind == OMPC_write) {
12561 enum {
12562 NotAnExpression,
12563 NotAnAssignmentOp,
12564 NotAScalarType,
12565 NotAnLValue,
12566 NoError
12567 } ErrorFound = NoError;
12568 SourceLocation ErrorLoc, NoteLoc;
12569 SourceRange ErrorRange, NoteRange;
12570 // If clause is write:
12571 // x = expr;
12572 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12573 const auto *AtomicBinOp =
12574 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12575 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12576 X = AtomicBinOp->getLHS();
12577 E = AtomicBinOp->getRHS();
12578 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12579 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12580 if (!X->isLValue()) {
12581 ErrorFound = NotAnLValue;
12582 ErrorLoc = AtomicBinOp->getExprLoc();
12583 ErrorRange = AtomicBinOp->getSourceRange();
12584 NoteLoc = X->getExprLoc();
12585 NoteRange = X->getSourceRange();
12586 }
12587 } else if (!X->isInstantiationDependent() ||
12588 !E->isInstantiationDependent()) {
12589 const Expr *NotScalarExpr =
12590 (X->isInstantiationDependent() || X->getType()->isScalarType())
12591 ? E
12592 : X;
12593 ErrorFound = NotAScalarType;
12594 ErrorLoc = AtomicBinOp->getExprLoc();
12595 ErrorRange = AtomicBinOp->getSourceRange();
12596 NoteLoc = NotScalarExpr->getExprLoc();
12597 NoteRange = NotScalarExpr->getSourceRange();
12598 }
12599 } else if (!AtomicBody->isInstantiationDependent()) {
12600 ErrorFound = NotAnAssignmentOp;
12601 ErrorLoc = AtomicBody->getExprLoc();
12602 ErrorRange = AtomicBody->getSourceRange();
12603 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12604 : AtomicBody->getExprLoc();
12605 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12606 : AtomicBody->getSourceRange();
12607 }
12608 } else {
12609 ErrorFound = NotAnExpression;
12610 NoteLoc = ErrorLoc = Body->getBeginLoc();
12611 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12612 }
12613 if (ErrorFound != NoError) {
12614 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12615 << ErrorRange;
12616 Diag(NoteLoc, diag::note_omp_atomic_read_write)
12617 << ErrorFound << NoteRange;
12618 return StmtError();
12619 }
12620 if (CurContext->isDependentContext())
12621 E = X = nullptr;
12622 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12623 // If clause is update:
12624 // x++;
12625 // x--;
12626 // ++x;
12627 // --x;
12628 // x binop= expr;
12629 // x = x binop expr;
12630 // x = expr binop x;
12631 OpenMPAtomicUpdateChecker Checker(*this);
12632 if (Checker.checkStatement(
12633 Body,
12634 (AtomicKind == OMPC_update)
12635 ? diag::err_omp_atomic_update_not_expression_statement
12636 : diag::err_omp_atomic_not_expression_statement,
12637 diag::note_omp_atomic_update))
12638 return StmtError();
12639 if (!CurContext->isDependentContext()) {
12640 E = Checker.getExpr();
12641 X = Checker.getX();
12642 UE = Checker.getUpdateExpr();
12643 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12644 }
12645 } else if (AtomicKind == OMPC_capture) {
12646 enum {
12647 NotAnAssignmentOp,
12648 NotACompoundStatement,
12649 NotTwoSubstatements,
12650 NotASpecificExpression,
12651 NoError
12652 } ErrorFound = NoError;
12653 SourceLocation ErrorLoc, NoteLoc;
12654 SourceRange ErrorRange, NoteRange;
12655 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12656 // If clause is a capture:
12657 // v = x++;
12658 // v = x--;
12659 // v = ++x;
12660 // v = --x;
12661 // v = x binop= expr;
12662 // v = x = x binop expr;
12663 // v = x = expr binop x;
12664 const auto *AtomicBinOp =
12665 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12666 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12667 V = AtomicBinOp->getLHS();
12668 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12669 OpenMPAtomicUpdateChecker Checker(*this);
12670 if (Checker.checkStatement(
12671 Body, diag::err_omp_atomic_capture_not_expression_statement,
12672 diag::note_omp_atomic_update))
12673 return StmtError();
12674 E = Checker.getExpr();
12675 X = Checker.getX();
12676 UE = Checker.getUpdateExpr();
12677 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12678 IsPostfixUpdate = Checker.isPostfixUpdate();
12679 } else if (!AtomicBody->isInstantiationDependent()) {
12680 ErrorLoc = AtomicBody->getExprLoc();
12681 ErrorRange = AtomicBody->getSourceRange();
12682 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12683 : AtomicBody->getExprLoc();
12684 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12685 : AtomicBody->getSourceRange();
12686 ErrorFound = NotAnAssignmentOp;
12687 }
12688 if (ErrorFound != NoError) {
12689 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12690 << ErrorRange;
12691 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12692 return StmtError();
12693 }
12694 if (CurContext->isDependentContext())
12695 UE = V = E = X = nullptr;
12696 } else {
12697 // If clause is a capture:
12698 // { v = x; x = expr; }
12699 // { v = x; x++; }
12700 // { v = x; x--; }
12701 // { v = x; ++x; }
12702 // { v = x; --x; }
12703 // { v = x; x binop= expr; }
12704 // { v = x; x = x binop expr; }
12705 // { v = x; x = expr binop x; }
12706 // { x++; v = x; }
12707 // { x--; v = x; }
12708 // { ++x; v = x; }
12709 // { --x; v = x; }
12710 // { x binop= expr; v = x; }
12711 // { x = x binop expr; v = x; }
12712 // { x = expr binop x; v = x; }
12713 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12714 // Check that this is { expr1; expr2; }
12715 if (CS->size() == 2) {
12716 Stmt *First = CS->body_front();
12717 Stmt *Second = CS->body_back();
12718 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12719 First = EWC->getSubExpr()->IgnoreParenImpCasts();
12720 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12721 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12722 // Need to find what subexpression is 'v' and what is 'x'.
12723 OpenMPAtomicUpdateChecker Checker(*this);
12724 bool IsUpdateExprFound = !Checker.checkStatement(Second);
12725 BinaryOperator *BinOp = nullptr;
12726 if (IsUpdateExprFound) {
12727 BinOp = dyn_cast<BinaryOperator>(First);
12728 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12729 }
12730 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12731 // { v = x; x++; }
12732 // { v = x; x--; }
12733 // { v = x; ++x; }
12734 // { v = x; --x; }
12735 // { v = x; x binop= expr; }
12736 // { v = x; x = x binop expr; }
12737 // { v = x; x = expr binop x; }
12738 // Check that the first expression has form v = x.
12739 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12740 llvm::FoldingSetNodeID XId, PossibleXId;
12741 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12742 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12743 IsUpdateExprFound = XId == PossibleXId;
12744 if (IsUpdateExprFound) {
12745 V = BinOp->getLHS();
12746 X = Checker.getX();
12747 E = Checker.getExpr();
12748 UE = Checker.getUpdateExpr();
12749 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12750 IsPostfixUpdate = true;
12751 }
12752 }
12753 if (!IsUpdateExprFound) {
12754 IsUpdateExprFound = !Checker.checkStatement(First);
12755 BinOp = nullptr;
12756 if (IsUpdateExprFound) {
12757 BinOp = dyn_cast<BinaryOperator>(Second);
12758 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12759 }
12760 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12761 // { x++; v = x; }
12762 // { x--; v = x; }
12763 // { ++x; v = x; }
12764 // { --x; v = x; }
12765 // { x binop= expr; v = x; }
12766 // { x = x binop expr; v = x; }
12767 // { x = expr binop x; v = x; }
12768 // Check that the second expression has form v = x.
12769 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12770 llvm::FoldingSetNodeID XId, PossibleXId;
12771 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12772 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12773 IsUpdateExprFound = XId == PossibleXId;
12774 if (IsUpdateExprFound) {
12775 V = BinOp->getLHS();
12776 X = Checker.getX();
12777 E = Checker.getExpr();
12778 UE = Checker.getUpdateExpr();
12779 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12780 IsPostfixUpdate = false;
12781 }
12782 }
12783 }
12784 if (!IsUpdateExprFound) {
12785 // { v = x; x = expr; }
12786 auto *FirstExpr = dyn_cast<Expr>(First);
12787 auto *SecondExpr = dyn_cast<Expr>(Second);
12788 if (!FirstExpr || !SecondExpr ||
12789 !(FirstExpr->isInstantiationDependent() ||
12790 SecondExpr->isInstantiationDependent())) {
12791 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12792 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12793 ErrorFound = NotAnAssignmentOp;
12794 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12795 : First->getBeginLoc();
12796 NoteRange = ErrorRange = FirstBinOp
12797 ? FirstBinOp->getSourceRange()
12798 : SourceRange(ErrorLoc, ErrorLoc);
12799 } else {
12800 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12801 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12802 ErrorFound = NotAnAssignmentOp;
12803 NoteLoc = ErrorLoc = SecondBinOp
12804 ? SecondBinOp->getOperatorLoc()
12805 : Second->getBeginLoc();
12806 NoteRange = ErrorRange =
12807 SecondBinOp ? SecondBinOp->getSourceRange()
12808 : SourceRange(ErrorLoc, ErrorLoc);
12809 } else {
12810 Expr *PossibleXRHSInFirst =
12811 FirstBinOp->getRHS()->IgnoreParenImpCasts();
12812 Expr *PossibleXLHSInSecond =
12813 SecondBinOp->getLHS()->IgnoreParenImpCasts();
12814 llvm::FoldingSetNodeID X1Id, X2Id;
12815 PossibleXRHSInFirst->Profile(X1Id, Context,
12816 /*Canonical=*/true);
12817 PossibleXLHSInSecond->Profile(X2Id, Context,
12818 /*Canonical=*/true);
12819 IsUpdateExprFound = X1Id == X2Id;
12820 if (IsUpdateExprFound) {
12821 V = FirstBinOp->getLHS();
12822 X = SecondBinOp->getLHS();
12823 E = SecondBinOp->getRHS();
12824 UE = nullptr;
12825 IsXLHSInRHSPart = false;
12826 IsPostfixUpdate = true;
12827 } else {
12828 ErrorFound = NotASpecificExpression;
12829 ErrorLoc = FirstBinOp->getExprLoc();
12830 ErrorRange = FirstBinOp->getSourceRange();
12831 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12832 NoteRange = SecondBinOp->getRHS()->getSourceRange();
12833 }
12834 }
12835 }
12836 }
12837 }
12838 } else {
12839 NoteLoc = ErrorLoc = Body->getBeginLoc();
12840 NoteRange = ErrorRange =
12841 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12842 ErrorFound = NotTwoSubstatements;
12843 }
12844 } else {
12845 NoteLoc = ErrorLoc = Body->getBeginLoc();
12846 NoteRange = ErrorRange =
12847 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12848 ErrorFound = NotACompoundStatement;
12849 }
12850 }
12851 if (ErrorFound != NoError) {
12852 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12853 << ErrorRange;
12854 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12855 return StmtError();
12856 }
12857 if (CurContext->isDependentContext())
12858 UE = V = E = X = nullptr;
12859 } else if (AtomicKind == OMPC_compare) {
12860 if (IsCompareCapture) {
12861 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12862 OpenMPAtomicCompareCaptureChecker Checker(*this);
12863 if (!Checker.checkStmt(Body, ErrorInfo)) {
12864 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12865 << ErrorInfo.ErrorRange;
12866 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12867 << ErrorInfo.Error << ErrorInfo.NoteRange;
12868 return StmtError();
12869 }
12870 X = Checker.getX();
12871 E = Checker.getE();
12872 D = Checker.getD();
12873 CE = Checker.getCond();
12874 V = Checker.getV();
12875 R = Checker.getR();
12876 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12877 IsXLHSInRHSPart = Checker.isXBinopExpr();
12878 IsFailOnly = Checker.isFailOnly();
12879 IsPostfixUpdate = Checker.isPostfixUpdate();
12880 } else {
12881 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12882 OpenMPAtomicCompareChecker Checker(*this);
12883 if (!Checker.checkStmt(Body, ErrorInfo)) {
12884 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12885 << ErrorInfo.ErrorRange;
12886 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12887 << ErrorInfo.Error << ErrorInfo.NoteRange;
12888 return StmtError();
12889 }
12890 X = Checker.getX();
12891 E = Checker.getE();
12892 D = Checker.getD();
12893 CE = Checker.getCond();
12894 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12895 IsXLHSInRHSPart = Checker.isXBinopExpr();
12896 }
12897 }
12898
12899 setFunctionHasBranchProtectedScope();
12900
12901 return OMPAtomicDirective::Create(
12902 Context, StartLoc, EndLoc, Clauses, AStmt,
12903 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
12904}
12905
12906StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
12907 Stmt *AStmt,
12908 SourceLocation StartLoc,
12909 SourceLocation EndLoc) {
12910 if (!AStmt)
12911 return StmtError();
12912
12913 auto *CS = cast<CapturedStmt>(AStmt);
12914 // 1.2.2 OpenMP Language Terminology
12915 // Structured block - An executable statement with a single entry at the
12916 // top and a single exit at the bottom.
12917 // The point of exit cannot be a branch out of the structured block.
12918 // longjmp() and throw() must not violate the entry/exit criteria.
12919 CS->getCapturedDecl()->setNothrow();
12920 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12921 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12922 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12923 // 1.2.2 OpenMP Language Terminology
12924 // Structured block - An executable statement with a single entry at the
12925 // top and a single exit at the bottom.
12926 // The point of exit cannot be a branch out of the structured block.
12927 // longjmp() and throw() must not violate the entry/exit criteria.
12928 CS->getCapturedDecl()->setNothrow();
12929 }
12930
12931 // OpenMP [2.16, Nesting of Regions]
12932 // If specified, a teams construct must be contained within a target
12933 // construct. That target construct must contain no statements or directives
12934 // outside of the teams construct.
12935 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
12936 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12937 bool OMPTeamsFound = true;
12938 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12939 auto I = CS->body_begin();
12940 while (I != CS->body_end()) {
12941 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12942 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12943 OMPTeamsFound) {
12944
12945 OMPTeamsFound = false;
12946 break;
12947 }
12948 ++I;
12949 }
12950 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", 12950, __extension__ __PRETTY_FUNCTION__
))
;
12951 S = *I;
12952 } else {
12953 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12954 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12955 }
12956 if (!OMPTeamsFound) {
12957 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12958 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
12959 diag::note_omp_nested_teams_construct_here);
12960 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12961 << isa<OMPExecutableDirective>(S);
12962 return StmtError();
12963 }
12964 }
12965
12966 setFunctionHasBranchProtectedScope();
12967
12968 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12969}
12970
12971StmtResult
12972Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
12973 Stmt *AStmt, SourceLocation StartLoc,
12974 SourceLocation EndLoc) {
12975 if (!AStmt)
12976 return StmtError();
12977
12978 auto *CS = cast<CapturedStmt>(AStmt);
12979 // 1.2.2 OpenMP Language Terminology
12980 // Structured block - An executable statement with a single entry at the
12981 // top and a single exit at the bottom.
12982 // The point of exit cannot be a branch out of the structured block.
12983 // longjmp() and throw() must not violate the entry/exit criteria.
12984 CS->getCapturedDecl()->setNothrow();
12985 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
12986 ThisCaptureLevel > 1; --ThisCaptureLevel) {
12987 CS = cast<CapturedStmt>(CS->getCapturedStmt());
12988 // 1.2.2 OpenMP Language Terminology
12989 // Structured block - An executable statement with a single entry at the
12990 // top and a single exit at the bottom.
12991 // The point of exit cannot be a branch out of the structured block.
12992 // longjmp() and throw() must not violate the entry/exit criteria.
12993 CS->getCapturedDecl()->setNothrow();
12994 }
12995
12996 setFunctionHasBranchProtectedScope();
12997
12998 return OMPTargetParallelDirective::Create(
12999 Context, StartLoc, EndLoc, Clauses, AStmt,
13000 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13001}
13002
13003StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13004 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13005 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13006 if (!AStmt)
13007 return StmtError();
13008
13009 auto *CS = cast<CapturedStmt>(AStmt);
13010 // 1.2.2 OpenMP Language Terminology
13011 // Structured block - An executable statement with a single entry at the
13012 // top and a single exit at the bottom.
13013 // The point of exit cannot be a branch out of the structured block.
13014 // longjmp() and throw() must not violate the entry/exit criteria.
13015 CS->getCapturedDecl()->setNothrow();
13016 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13017 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13018 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13019 // 1.2.2 OpenMP Language Terminology
13020 // Structured block - An executable statement with a single entry at the
13021 // top and a single exit at the bottom.
13022 // The point of exit cannot be a branch out of the structured block.
13023 // longjmp() and throw() must not violate the entry/exit criteria.
13024 CS->getCapturedDecl()->setNothrow();
13025 }
13026
13027 OMPLoopBasedDirective::HelperExprs B;
13028 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13029 // define the nested loops number.
13030 unsigned NestedLoopCount =
13031 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13032 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13033 VarsWithImplicitDSA, B);
13034 if (NestedLoopCount == 0)
13035 return StmtError();
13036
13037 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", 13038, __extension__ __PRETTY_FUNCTION__
))
13038 "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", 13038, __extension__ __PRETTY_FUNCTION__
))
;
13039
13040 if (!CurContext->isDependentContext()) {
13041 // Finalize the clauses that need pre-built expressions for CodeGen.
13042 for (OMPClause *C : Clauses) {
13043 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13044 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13045 B.NumIterations, *this, CurScope,
13046 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13047 return StmtError();
13048 }
13049 }
13050
13051 setFunctionHasBranchProtectedScope();
13052 return OMPTargetParallelForDirective::Create(
13053 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13054 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13055}
13056
13057/// Check for existence of a map clause in the list of clauses.
13058static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13059 const OpenMPClauseKind K) {
13060 return llvm::any_of(
13061 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13062}
13063
13064template <typename... Params>
13065static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13066 const Params... ClauseTypes) {
13067 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13068}
13069
13070/// Check if the variables in the mapping clause are externally visible.
13071static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13072 for (const OMPClause *C : Clauses) {
13073 if (auto *TC = dyn_cast<OMPToClause>(C))
13074 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13075 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13076 (VD->isExternallyVisible() &&
13077 VD->getVisibility() != HiddenVisibility);
13078 });
13079 else if (auto *FC = dyn_cast<OMPFromClause>(C))
13080 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13081 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13082 (VD->isExternallyVisible() &&
13083 VD->getVisibility() != HiddenVisibility);
13084 });
13085 }
13086
13087 return true;
13088}
13089
13090StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13091 Stmt *AStmt,
13092 SourceLocation StartLoc,
13093 SourceLocation EndLoc) {
13094 if (!AStmt)
13095 return StmtError();
13096
13097 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", 13097, __extension__ __PRETTY_FUNCTION__
))
;
13098
13099 // OpenMP [2.12.2, target data Construct, Restrictions]
13100 // At least one map, use_device_addr or use_device_ptr clause must appear on
13101 // the directive.
13102 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13103 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13104 StringRef Expected;
13105 if (LangOpts.OpenMP < 50)
13106 Expected = "'map' or 'use_device_ptr'";
13107 else
13108 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13109 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13110 << Expected << getOpenMPDirectiveName(OMPD_target_data);
13111 return StmtError();
13112 }
13113
13114 setFunctionHasBranchProtectedScope();
13115
13116 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13117 AStmt);
13118}
13119
13120StmtResult
13121Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13122 SourceLocation StartLoc,
13123 SourceLocation EndLoc, Stmt *AStmt) {
13124 if (!AStmt)
13125 return StmtError();
13126
13127 auto *CS = cast<CapturedStmt>(AStmt);
13128 // 1.2.2 OpenMP Language Terminology
13129 // Structured block - An executable statement with a single entry at the
13130 // top and a single exit at the bottom.
13131 // The point of exit cannot be a branch out of the structured block.
13132 // longjmp() and throw() must not violate the entry/exit criteria.
13133 CS->getCapturedDecl()->setNothrow();
13134 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13135 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13136 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13137 // 1.2.2 OpenMP Language Terminology
13138 // Structured block - An executable statement with a single entry at the
13139 // top and a single exit at the bottom.
13140 // The point of exit cannot be a branch out of the structured block.
13141 // longjmp() and throw() must not violate the entry/exit criteria.
13142 CS->getCapturedDecl()->setNothrow();
13143 }
13144
13145 // OpenMP [2.10.2, Restrictions, p. 99]
13146 // At least one map clause must appear on the directive.
13147 if (!hasClauses(Clauses, OMPC_map)) {
13148 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13149 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13150 return StmtError();
13151 }
13152
13153 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13154 AStmt);
13155}
13156
13157StmtResult
13158Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13159 SourceLocation StartLoc,
13160 SourceLocation EndLoc, Stmt *AStmt) {
13161 if (!AStmt)
13162 return StmtError();
13163
13164 auto *CS = cast<CapturedStmt>(AStmt);
13165 // 1.2.2 OpenMP Language Terminology
13166 // Structured block - An executable statement with a single entry at the
13167 // top and a single exit at the bottom.
13168 // The point of exit cannot be a branch out of the structured block.
13169 // longjmp() and throw() must not violate the entry/exit criteria.
13170 CS->getCapturedDecl()->setNothrow();
13171 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13172 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13173 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13174 // 1.2.2 OpenMP Language Terminology
13175 // Structured block - An executable statement with a single entry at the
13176 // top and a single exit at the bottom.
13177 // The point of exit cannot be a branch out of the structured block.
13178 // longjmp() and throw() must not violate the entry/exit criteria.
13179 CS->getCapturedDecl()->setNothrow();
13180 }
13181
13182 // OpenMP [2.10.3, Restrictions, p. 102]
13183 // At least one map clause must appear on the directive.
13184 if (!hasClauses(Clauses, OMPC_map)) {
13185 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13186 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13187 return StmtError();
13188 }
13189
13190 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13191 AStmt);
13192}
13193
13194StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13195 SourceLocation StartLoc,
13196 SourceLocation EndLoc,
13197 Stmt *AStmt) {
13198 if (!AStmt)
13199 return StmtError();
13200
13201 auto *CS = cast<CapturedStmt>(AStmt);
13202 // 1.2.2 OpenMP Language Terminology
13203 // Structured block - An executable statement with a single entry at the
13204 // top and a single exit at the bottom.
13205 // The point of exit cannot be a branch out of the structured block.
13206 // longjmp() and throw() must not violate the entry/exit criteria.
13207 CS->getCapturedDecl()->setNothrow();
13208 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13209 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13210 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13211 // 1.2.2 OpenMP Language Terminology
13212 // Structured block - An executable statement with a single entry at the
13213 // top and a single exit at the bottom.
13214 // The point of exit cannot be a branch out of the structured block.
13215 // longjmp() and throw() must not violate the entry/exit criteria.
13216 CS->getCapturedDecl()->setNothrow();
13217 }
13218
13219 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13220 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13221 return StmtError();
13222 }
13223
13224 if (!isClauseMappable(Clauses)) {
13225 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13226 return StmtError();
13227 }
13228
13229 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13230 AStmt);
13231}
13232
13233StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13234 Stmt *AStmt, SourceLocation StartLoc,
13235 SourceLocation EndLoc) {
13236 if (!AStmt)
13237 return StmtError();
13238
13239 auto *CS = cast<CapturedStmt>(AStmt);
13240 // 1.2.2 OpenMP Language Terminology
13241 // Structured block - An executable statement with a single entry at the
13242 // top and a single exit at the bottom.
13243 // The point of exit cannot be a branch out of the structured block.
13244 // longjmp() and throw() must not violate the entry/exit criteria.
13245 CS->getCapturedDecl()->setNothrow();
13246
13247 setFunctionHasBranchProtectedScope();
13248
13249 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
13250
13251 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13252}
13253
13254StmtResult
13255Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13256 SourceLocation EndLoc,
13257 OpenMPDirectiveKind CancelRegion) {
13258 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
13259 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13260 return StmtError();
13261 }
13262 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
13263 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13264 return StmtError();
13265 }
13266 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13267 CancelRegion);
13268}
13269
13270StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13271 SourceLocation StartLoc,
13272 SourceLocation EndLoc,
13273 OpenMPDirectiveKind CancelRegion) {
13274 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
13275 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13276 return StmtError();
13277 }
13278 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
13279 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13280 return StmtError();
13281 }
13282 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
13283 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13284 CancelRegion);
13285}
13286
13287static bool checkReductionClauseWithNogroup(Sema &S,
13288 ArrayRef<OMPClause *> Clauses) {
13289 const OMPClause *ReductionClause = nullptr;
13290 const OMPClause *NogroupClause = nullptr;
13291 for (const OMPClause *C : Clauses) {
13292 if (C->getClauseKind() == OMPC_reduction) {
13293 ReductionClause = C;
13294 if (NogroupClause)
13295 break;
13296 continue;
13297 }
13298 if (C->getClauseKind() == OMPC_nogroup) {
13299 NogroupClause = C;
13300 if (ReductionClause)
13301 break;
13302 continue;
13303 }
13304 }
13305 if (ReductionClause && NogroupClause) {
13306 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13307 << SourceRange(NogroupClause->getBeginLoc(),
13308 NogroupClause->getEndLoc());
13309 return true;
13310 }
13311 return false;
13312}
13313
13314StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13315 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13316 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13317 if (!AStmt)
13318 return StmtError();
13319
13320 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", 13320, __extension__ __PRETTY_FUNCTION__
))
;
13321 OMPLoopBasedDirective::HelperExprs B;
13322 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13323 // define the nested loops number.
13324 unsigned NestedLoopCount =
13325 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13326 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13327 VarsWithImplicitDSA, B);
13328 if (NestedLoopCount == 0)
13329 return StmtError();
13330
13331 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", 13332, __extension__ __PRETTY_FUNCTION__
))
13332 "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", 13332, __extension__ __PRETTY_FUNCTION__
))
;
13333
13334 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13335 // The grainsize clause and num_tasks clause are mutually exclusive and may
13336 // not appear on the same taskloop directive.
13337 if (checkMutuallyExclusiveClauses(*this, Clauses,
13338 {OMPC_grainsize, OMPC_num_tasks}))
13339 return StmtError();
13340 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13341 // If a reduction clause is present on the taskloop directive, the nogroup
13342 // clause must not be specified.
13343 if (checkReductionClauseWithNogroup(*this, Clauses))
13344 return StmtError();
13345
13346 setFunctionHasBranchProtectedScope();
13347 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13348 NestedLoopCount, Clauses, AStmt, B,
13349 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13350}
13351
13352StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13353 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13354 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13355 if (!AStmt)
13356 return StmtError();
13357
13358 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", 13358, __extension__ __PRETTY_FUNCTION__
))
;
13359 OMPLoopBasedDirective::HelperExprs B;
13360 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13361 // define the nested loops number.
13362 unsigned NestedLoopCount =
13363 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13364 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13365 VarsWithImplicitDSA, B);
13366 if (NestedLoopCount == 0)
13367 return StmtError();
13368
13369 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", 13370, __extension__ __PRETTY_FUNCTION__
))
13370 "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", 13370, __extension__ __PRETTY_FUNCTION__
))
;
13371
13372 if (!CurContext->isDependentContext()) {
13373 // Finalize the clauses that need pre-built expressions for CodeGen.
13374 for (OMPClause *C : Clauses) {
13375 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13376 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13377 B.NumIterations, *this, CurScope,
13378 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13379 return StmtError();
13380 }
13381 }
13382
13383 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13384 // The grainsize clause and num_tasks clause are mutually exclusive and may
13385 // not appear on the same taskloop directive.
13386 if (checkMutuallyExclusiveClauses(*this, Clauses,
13387 {OMPC_grainsize, OMPC_num_tasks}))
13388 return StmtError();
13389 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13390 // If a reduction clause is present on the taskloop directive, the nogroup
13391 // clause must not be specified.
13392 if (checkReductionClauseWithNogroup(*this, Clauses))
13393 return StmtError();
13394 if (checkSimdlenSafelenSpecified(*this, Clauses))
13395 return StmtError();
13396
13397 setFunctionHasBranchProtectedScope();
13398 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13399 NestedLoopCount, Clauses, AStmt, B);
13400}
13401
13402StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13403 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13404 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13405 if (!AStmt)
13406 return StmtError();
13407
13408 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", 13408, __extension__ __PRETTY_FUNCTION__
))
;
13409 OMPLoopBasedDirective::HelperExprs B;
13410 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13411 // define the nested loops number.
13412 unsigned NestedLoopCount =
13413 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13414 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13415 VarsWithImplicitDSA, B);
13416 if (NestedLoopCount == 0)
13417 return StmtError();
13418
13419 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", 13420, __extension__ __PRETTY_FUNCTION__
))
13420 "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", 13420, __extension__ __PRETTY_FUNCTION__
))
;
13421
13422 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13423 // The grainsize clause and num_tasks clause are mutually exclusive and may
13424 // not appear on the same taskloop directive.
13425 if (checkMutuallyExclusiveClauses(*this, Clauses,
13426 {OMPC_grainsize, OMPC_num_tasks}))
13427 return StmtError();
13428 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13429 // If a reduction clause is present on the taskloop directive, the nogroup
13430 // clause must not be specified.
13431 if (checkReductionClauseWithNogroup(*this, Clauses))
13432 return StmtError();
13433
13434 setFunctionHasBranchProtectedScope();
13435 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13436 NestedLoopCount, Clauses, AStmt, B,
13437 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13438}
13439
13440StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13441 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13442 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13443 if (!AStmt)
13444 return StmtError();
13445
13446 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", 13446, __extension__ __PRETTY_FUNCTION__
))
;
13447 OMPLoopBasedDirective::HelperExprs B;
13448 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13449 // define the nested loops number.
13450 unsigned NestedLoopCount =
13451 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13452 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13453 VarsWithImplicitDSA, B);
13454 if (NestedLoopCount == 0)
13455 return StmtError();
13456
13457 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", 13458, __extension__ __PRETTY_FUNCTION__
))
13458 "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", 13458, __extension__ __PRETTY_FUNCTION__
))
;
13459
13460 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13461 // The grainsize clause and num_tasks clause are mutually exclusive and may
13462 // not appear on the same taskloop directive.
13463 if (checkMutuallyExclusiveClauses(*this, Clauses,
13464 {OMPC_grainsize, OMPC_num_tasks}))
13465 return StmtError();
13466 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13467 // If a reduction clause is present on the taskloop directive, the nogroup
13468 // clause must not be specified.
13469 if (checkReductionClauseWithNogroup(*this, Clauses))
13470 return StmtError();
13471
13472 setFunctionHasBranchProtectedScope();
13473 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13474 NestedLoopCount, Clauses, AStmt, B,
13475 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13476}
13477
13478StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13479 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13480 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13481 if (!AStmt)
13482 return StmtError();
13483
13484 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", 13484, __extension__ __PRETTY_FUNCTION__
))
;
13485 OMPLoopBasedDirective::HelperExprs B;
13486 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13487 // define the nested loops number.
13488 unsigned NestedLoopCount =
13489 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13490 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13491 VarsWithImplicitDSA, B);
13492 if (NestedLoopCount == 0)
13493 return StmtError();
13494
13495 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", 13496, __extension__ __PRETTY_FUNCTION__
))
13496 "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", 13496, __extension__ __PRETTY_FUNCTION__
))
;
13497
13498 if (!CurContext->isDependentContext()) {
13499 // Finalize the clauses that need pre-built expressions for CodeGen.
13500 for (OMPClause *C : Clauses) {
13501 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13502 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13503 B.NumIterations, *this, CurScope,
13504 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13505 return StmtError();
13506 }
13507 }
13508
13509 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13510 // The grainsize clause and num_tasks clause are mutually exclusive and may
13511 // not appear on the same taskloop directive.
13512 if (checkMutuallyExclusiveClauses(*this, Clauses,
13513 {OMPC_grainsize, OMPC_num_tasks}))
13514 return StmtError();
13515 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13516 // If a reduction clause is present on the taskloop directive, the nogroup
13517 // clause must not be specified.
13518 if (checkReductionClauseWithNogroup(*this, Clauses))
13519 return StmtError();
13520 if (checkSimdlenSafelenSpecified(*this, Clauses))
13521 return StmtError();
13522
13523 setFunctionHasBranchProtectedScope();
13524 return OMPMasterTaskLoopSimdDirective::Create(
13525 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13526}
13527
13528StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13529 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13530 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13531 if (!AStmt)
13532 return StmtError();
13533
13534 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", 13534, __extension__ __PRETTY_FUNCTION__
))
;
13535 OMPLoopBasedDirective::HelperExprs B;
13536 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13537 // define the nested loops number.
13538 unsigned NestedLoopCount =
13539 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13540 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13541 VarsWithImplicitDSA, B);
13542 if (NestedLoopCount == 0)
13543 return StmtError();
13544
13545 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", 13546, __extension__ __PRETTY_FUNCTION__
))
13546 "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", 13546, __extension__ __PRETTY_FUNCTION__
))
;
13547
13548 if (!CurContext->isDependentContext()) {
13549 // Finalize the clauses that need pre-built expressions for CodeGen.
13550 for (OMPClause *C : Clauses) {
13551 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13552 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13553 B.NumIterations, *this, CurScope,
13554 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13555 return StmtError();
13556 }
13557 }
13558
13559 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13560 // The grainsize clause and num_tasks clause are mutually exclusive and may
13561 // not appear on the same taskloop directive.
13562 if (checkMutuallyExclusiveClauses(*this, Clauses,
13563 {OMPC_grainsize, OMPC_num_tasks}))
13564 return StmtError();
13565 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13566 // If a reduction clause is present on the taskloop directive, the nogroup
13567 // clause must not be specified.
13568 if (checkReductionClauseWithNogroup(*this, Clauses))
13569 return StmtError();
13570 if (checkSimdlenSafelenSpecified(*this, Clauses))
13571 return StmtError();
13572
13573 setFunctionHasBranchProtectedScope();
13574 return OMPMaskedTaskLoopSimdDirective::Create(
13575 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13576}
13577
13578StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13579 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13580 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13581 if (!AStmt)
13582 return StmtError();
13583
13584 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", 13584, __extension__ __PRETTY_FUNCTION__
))
;
13585 auto *CS = cast<CapturedStmt>(AStmt);
13586 // 1.2.2 OpenMP Language Terminology
13587 // Structured block - An executable statement with a single entry at the
13588 // top and a single exit at the bottom.
13589 // The point of exit cannot be a branch out of the structured block.
13590 // longjmp() and throw() must not violate the entry/exit criteria.
13591 CS->getCapturedDecl()->setNothrow();
13592 for (int ThisCaptureLevel =
13593 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13594 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13595 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13596 // 1.2.2 OpenMP Language Terminology
13597 // Structured block - An executable statement with a single entry at the
13598 // top and a single exit at the bottom.
13599 // The point of exit cannot be a branch out of the structured block.
13600 // longjmp() and throw() must not violate the entry/exit criteria.
13601 CS->getCapturedDecl()->setNothrow();
13602 }
13603
13604 OMPLoopBasedDirective::HelperExprs B;
13605 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13606 // define the nested loops number.
13607 unsigned NestedLoopCount = checkOpenMPLoop(
13608 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13609 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13610 VarsWithImplicitDSA, B);
13611 if (NestedLoopCount == 0)
13612 return StmtError();
13613
13614 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", 13615, __extension__ __PRETTY_FUNCTION__
))
13615 "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", 13615, __extension__ __PRETTY_FUNCTION__
))
;
13616
13617 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13618 // The grainsize clause and num_tasks clause are mutually exclusive and may
13619 // not appear on the same taskloop directive.
13620 if (checkMutuallyExclusiveClauses(*this, Clauses,
13621 {OMPC_grainsize, OMPC_num_tasks}))
13622 return StmtError();
13623 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13624 // If a reduction clause is present on the taskloop directive, the nogroup
13625 // clause must not be specified.
13626 if (checkReductionClauseWithNogroup(*this, Clauses))
13627 return StmtError();
13628
13629 setFunctionHasBranchProtectedScope();
13630 return OMPParallelMasterTaskLoopDirective::Create(
13631 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13632 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13633}
13634
13635StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13636 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13637 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13638 if (!AStmt)
13639 return StmtError();
13640
13641 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", 13641, __extension__ __PRETTY_FUNCTION__
))
;
13642 auto *CS = cast<CapturedStmt>(AStmt);
13643 // 1.2.2 OpenMP Language Terminology
13644 // Structured block - An executable statement with a single entry at the
13645 // top and a single exit at the bottom.
13646 // The point of exit cannot be a branch out of the structured block.
13647 // longjmp() and throw() must not violate the entry/exit criteria.
13648 CS->getCapturedDecl()->setNothrow();
13649 for (int ThisCaptureLevel =
13650 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13651 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13652 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13653 // 1.2.2 OpenMP Language Terminology
13654 // Structured block - An executable statement with a single entry at the
13655 // top and a single exit at the bottom.
13656 // The point of exit cannot be a branch out of the structured block.
13657 // longjmp() and throw() must not violate the entry/exit criteria.
13658 CS->getCapturedDecl()->setNothrow();
13659 }
13660
13661 OMPLoopBasedDirective::HelperExprs B;
13662 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13663 // define the nested loops number.
13664 unsigned NestedLoopCount = checkOpenMPLoop(
13665 OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13666 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13667 VarsWithImplicitDSA, B);
13668 if (NestedLoopCount == 0)
13669 return StmtError();
13670
13671 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", 13672, __extension__ __PRETTY_FUNCTION__
))
13672 "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", 13672, __extension__ __PRETTY_FUNCTION__
))
;
13673
13674 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13675 // The grainsize clause and num_tasks clause are mutually exclusive and may
13676 // not appear on the same taskloop directive.
13677 if (checkMutuallyExclusiveClauses(*this, Clauses,
13678 {OMPC_grainsize, OMPC_num_tasks}))
13679 return StmtError();
13680 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13681 // If a reduction clause is present on the taskloop directive, the nogroup
13682 // clause must not be specified.
13683 if (checkReductionClauseWithNogroup(*this, Clauses))
13684 return StmtError();
13685
13686 setFunctionHasBranchProtectedScope();
13687 return OMPParallelMaskedTaskLoopDirective::Create(
13688 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13689 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13690}
13691
13692StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13693 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13694 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13695 if (!AStmt)
13696 return StmtError();
13697
13698 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", 13698, __extension__ __PRETTY_FUNCTION__
))
;
13699 auto *CS = cast<CapturedStmt>(AStmt);
13700 // 1.2.2 OpenMP Language Terminology
13701 // Structured block - An executable statement with a single entry at the
13702 // top and a single exit at the bottom.
13703 // The point of exit cannot be a branch out of the structured block.
13704 // longjmp() and throw() must not violate the entry/exit criteria.
13705 CS->getCapturedDecl()->setNothrow();
13706 for (int ThisCaptureLevel =
13707 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13708 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13709 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13710 // 1.2.2 OpenMP Language Terminology
13711 // Structured block - An executable statement with a single entry at the
13712 // top and a single exit at the bottom.
13713 // The point of exit cannot be a branch out of the structured block.
13714 // longjmp() and throw() must not violate the entry/exit criteria.
13715 CS->getCapturedDecl()->setNothrow();
13716 }
13717
13718 OMPLoopBasedDirective::HelperExprs B;
13719 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13720 // define the nested loops number.
13721 unsigned NestedLoopCount = checkOpenMPLoop(
13722 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13723 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13724 VarsWithImplicitDSA, B);
13725 if (NestedLoopCount == 0)
13726 return StmtError();
13727
13728 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", 13729, __extension__ __PRETTY_FUNCTION__
))
13729 "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", 13729, __extension__ __PRETTY_FUNCTION__
))
;
13730
13731 if (!CurContext->isDependentContext()) {
13732 // Finalize the clauses that need pre-built expressions for CodeGen.
13733 for (OMPClause *C : Clauses) {
13734 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13735 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13736 B.NumIterations, *this, CurScope,
13737 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13738 return StmtError();
13739 }
13740 }
13741
13742 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13743 // The grainsize clause and num_tasks clause are mutually exclusive and may
13744 // not appear on the same taskloop directive.
13745 if (checkMutuallyExclusiveClauses(*this, Clauses,
13746 {OMPC_grainsize, OMPC_num_tasks}))
13747 return StmtError();
13748 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13749 // If a reduction clause is present on the taskloop directive, the nogroup
13750 // clause must not be specified.
13751 if (checkReductionClauseWithNogroup(*this, Clauses))
13752 return StmtError();
13753 if (checkSimdlenSafelenSpecified(*this, Clauses))
13754 return StmtError();
13755
13756 setFunctionHasBranchProtectedScope();
13757 return OMPParallelMasterTaskLoopSimdDirective::Create(
13758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13759}
13760
13761StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
13762 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13763 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13764 if (!AStmt)
13765 return StmtError();
13766
13767 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", 13767, __extension__ __PRETTY_FUNCTION__
))
;
13768 auto *CS = cast<CapturedStmt>(AStmt);
13769 // 1.2.2 OpenMP Language Terminology
13770 // Structured block - An executable statement with a single entry at the
13771 // top and a single exit at the bottom.
13772 // The point of exit cannot be a branch out of the structured block.
13773 // longjmp() and throw() must not violate the entry/exit criteria.
13774 CS->getCapturedDecl()->setNothrow();
13775 for (int ThisCaptureLevel =
13776 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
13777 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13778 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13779 // 1.2.2 OpenMP Language Terminology
13780 // Structured block - An executable statement with a single entry at the
13781 // top and a single exit at the bottom.
13782 // The point of exit cannot be a branch out of the structured block.
13783 // longjmp() and throw() must not violate the entry/exit criteria.
13784 CS->getCapturedDecl()->setNothrow();
13785 }
13786
13787 OMPLoopBasedDirective::HelperExprs B;
13788 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13789 // define the nested loops number.
13790 unsigned NestedLoopCount = checkOpenMPLoop(
13791 OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13792 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13793 VarsWithImplicitDSA, B);
13794 if (NestedLoopCount == 0)
13795 return StmtError();
13796
13797 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", 13798, __extension__ __PRETTY_FUNCTION__
))
13798 "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", 13798, __extension__ __PRETTY_FUNCTION__
))
;
13799
13800 if (!CurContext->isDependentContext()) {
13801 // Finalize the clauses that need pre-built expressions for CodeGen.
13802 for (OMPClause *C : Clauses) {
13803 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13804 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13805 B.NumIterations, *this, CurScope,
13806 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13807 return StmtError();
13808 }
13809 }
13810
13811 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13812 // The grainsize clause and num_tasks clause are mutually exclusive and may
13813 // not appear on the same taskloop directive.
13814 if (checkMutuallyExclusiveClauses(*this, Clauses,
13815 {OMPC_grainsize, OMPC_num_tasks}))
13816 return StmtError();
13817 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13818 // If a reduction clause is present on the taskloop directive, the nogroup
13819 // clause must not be specified.
13820 if (checkReductionClauseWithNogroup(*this, Clauses))
13821 return StmtError();
13822 if (checkSimdlenSafelenSpecified(*this, Clauses))
13823 return StmtError();
13824
13825 setFunctionHasBranchProtectedScope();
13826 return OMPParallelMaskedTaskLoopSimdDirective::Create(
13827 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13828}
13829
13830StmtResult Sema::ActOnOpenMPDistributeDirective(
13831 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13832 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13833 if (!AStmt)
13834 return StmtError();
13835
13836 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", 13836, __extension__ __PRETTY_FUNCTION__
))
;
13837 OMPLoopBasedDirective::HelperExprs B;
13838 // In presence of clause 'collapse' with number of loops, it will
13839 // define the nested loops number.
13840 unsigned NestedLoopCount =
13841 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13842 nullptr /*ordered not a clause on distribute*/, AStmt,
13843 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13844 if (NestedLoopCount == 0)
13845 return StmtError();
13846
13847 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", 13848, __extension__ __PRETTY_FUNCTION__
))
13848 "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", 13848, __extension__ __PRETTY_FUNCTION__
))
;
13849
13850 setFunctionHasBranchProtectedScope();
13851 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13852 NestedLoopCount, Clauses, AStmt, B);
13853}
13854
13855StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
13856 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13857 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13858 if (!AStmt)
13859 return StmtError();
13860
13861 auto *CS = cast<CapturedStmt>(AStmt);
13862 // 1.2.2 OpenMP Language Terminology
13863 // Structured block - An executable statement with a single entry at the
13864 // top and a single exit at the bottom.
13865 // The point of exit cannot be a branch out of the structured block.
13866 // longjmp() and throw() must not violate the entry/exit criteria.
13867 CS->getCapturedDecl()->setNothrow();
13868 for (int ThisCaptureLevel =
13869 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13870 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13871 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13872 // 1.2.2 OpenMP Language Terminology
13873 // Structured block - An executable statement with a single entry at the
13874 // top and a single exit at the bottom.
13875 // The point of exit cannot be a branch out of the structured block.
13876 // longjmp() and throw() must not violate the entry/exit criteria.
13877 CS->getCapturedDecl()->setNothrow();
13878 }
13879
13880 OMPLoopBasedDirective::HelperExprs B;
13881 // In presence of clause 'collapse' with number of loops, it will
13882 // define the nested loops number.
13883 unsigned NestedLoopCount = checkOpenMPLoop(
13884 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13885 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13886 VarsWithImplicitDSA, B);
13887 if (NestedLoopCount == 0)
13888 return StmtError();
13889
13890 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", 13891, __extension__ __PRETTY_FUNCTION__
))
13891 "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", 13891, __extension__ __PRETTY_FUNCTION__
))
;
13892
13893 setFunctionHasBranchProtectedScope();
13894 return OMPDistributeParallelForDirective::Create(
13895 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13896 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
13897}
13898
13899StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
13900 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13901 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13902 if (!AStmt)
13903 return StmtError();
13904
13905 auto *CS = cast<CapturedStmt>(AStmt);
13906 // 1.2.2 OpenMP Language Terminology
13907 // Structured block - An executable statement with a single entry at the
13908 // top and a single exit at the bottom.
13909 // The point of exit cannot be a branch out of the structured block.
13910 // longjmp() and throw() must not violate the entry/exit criteria.
13911 CS->getCapturedDecl()->setNothrow();
13912 for (int ThisCaptureLevel =
13913 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13914 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13915 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13916 // 1.2.2 OpenMP Language Terminology
13917 // Structured block - An executable statement with a single entry at the
13918 // top and a single exit at the bottom.
13919 // The point of exit cannot be a branch out of the structured block.
13920 // longjmp() and throw() must not violate the entry/exit criteria.
13921 CS->getCapturedDecl()->setNothrow();
13922 }
13923
13924 OMPLoopBasedDirective::HelperExprs B;
13925 // In presence of clause 'collapse' with number of loops, it will
13926 // define the nested loops number.
13927 unsigned NestedLoopCount = checkOpenMPLoop(
13928 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13929 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
13930 VarsWithImplicitDSA, B);
13931 if (NestedLoopCount == 0)
13932 return StmtError();
13933
13934 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", 13935, __extension__ __PRETTY_FUNCTION__
))
13935 "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", 13935, __extension__ __PRETTY_FUNCTION__
))
;
13936
13937 if (!CurContext->isDependentContext()) {
13938 // Finalize the clauses that need pre-built expressions for CodeGen.
13939 for (OMPClause *C : Clauses) {
13940 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13941 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13942 B.NumIterations, *this, CurScope,
13943 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
13944 return StmtError();
13945 }
13946 }
13947
13948 if (checkSimdlenSafelenSpecified(*this, Clauses))
13949 return StmtError();
13950
13951 setFunctionHasBranchProtectedScope();
13952 return OMPDistributeParallelForSimdDirective::Create(
13953 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13954}
13955
13956StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
13957 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13958 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13959 if (!AStmt)
13960 return StmtError();
13961
13962 auto *CS = cast<CapturedStmt>(AStmt);
13963 // 1.2.2 OpenMP Language Terminology
13964 // Structured block - An executable statement with a single entry at the
13965 // top and a single exit at the bottom.
13966 // The point of exit cannot be a branch out of the structured block.
13967 // longjmp() and throw() must not violate the entry/exit criteria.
13968 CS->getCapturedDecl()->setNothrow();
13969 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
13970 ThisCaptureLevel > 1; --ThisCaptureLevel) {
13971 CS = cast<CapturedStmt>(CS->getCapturedStmt());
13972 // 1.2.2 OpenMP Language Terminology
13973 // Structured block - An executable statement with a single entry at the
13974 // top and a single exit at the bottom.
13975 // The point of exit cannot be a branch out of the structured block.
13976 // longjmp() and throw() must not violate the entry/exit criteria.
13977 CS->getCapturedDecl()->setNothrow();
13978 }
13979
13980 OMPLoopBasedDirective::HelperExprs B;
13981 // In presence of clause 'collapse' with number of loops, it will
13982 // define the nested loops number.
13983 unsigned NestedLoopCount =
13984 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13985 nullptr /*ordered not a clause on distribute*/, CS, *this,
13986 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
13987 if (NestedLoopCount == 0)
13988 return StmtError();
13989
13990 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", 13991, __extension__ __PRETTY_FUNCTION__
))
13991 "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", 13991, __extension__ __PRETTY_FUNCTION__
))
;
13992
13993 if (!CurContext->isDependentContext()) {
13994 // Finalize the clauses that need pre-built expressions for CodeGen.
13995 for (OMPClause *C : Clauses) {
13996 if (auto *LC = dyn_cast<OMPLinearClause>(C))
13997 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13998 B.NumIterations, *this, CurScope,
13999 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14000 return StmtError();
14001 }
14002 }
14003
14004 if (checkSimdlenSafelenSpecified(*this, Clauses))
14005 return StmtError();
14006
14007 setFunctionHasBranchProtectedScope();
14008 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14009 NestedLoopCount, Clauses, AStmt, B);
14010}
14011
14012StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14013 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14014 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14015 if (!AStmt)
14016 return StmtError();
14017
14018 auto *CS = cast<CapturedStmt>(AStmt);
14019 // 1.2.2 OpenMP Language Terminology
14020 // Structured block - An executable statement with a single entry at the
14021 // top and a single exit at the bottom.
14022 // The point of exit cannot be a branch out of the structured block.
14023 // longjmp() and throw() must not violate the entry/exit criteria.
14024 CS->getCapturedDecl()->setNothrow();
14025 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14026 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14027 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14028 // 1.2.2 OpenMP Language Terminology
14029 // Structured block - An executable statement with a single entry at the
14030 // top and a single exit at the bottom.
14031 // The point of exit cannot be a branch out of the structured block.
14032 // longjmp() and throw() must not violate the entry/exit criteria.
14033 CS->getCapturedDecl()->setNothrow();
14034 }
14035
14036 OMPLoopBasedDirective::HelperExprs B;
14037 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14038 // define the nested loops number.
14039 unsigned NestedLoopCount = checkOpenMPLoop(
14040 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14041 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA,
14042 B);
14043 if (NestedLoopCount == 0)
14044 return StmtError();
14045
14046 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", 14047, __extension__ __PRETTY_FUNCTION__
))
14047 "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", 14047, __extension__ __PRETTY_FUNCTION__
))
;
14048
14049 if (!CurContext->isDependentContext()) {
14050 // Finalize the clauses that need pre-built expressions for CodeGen.
14051 for (OMPClause *C : Clauses) {
14052 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14053 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14054 B.NumIterations, *this, CurScope,
14055 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14056 return StmtError();
14057 }
14058 }
14059 if (checkSimdlenSafelenSpecified(*this, Clauses))
14060 return StmtError();
14061
14062 setFunctionHasBranchProtectedScope();
14063 return OMPTargetParallelForSimdDirective::Create(
14064 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14065}
14066
14067StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14068 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14069 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14070 if (!AStmt)
14071 return StmtError();
14072
14073 auto *CS = cast<CapturedStmt>(AStmt);
14074 // 1.2.2 OpenMP Language Terminology
14075 // Structured block - An executable statement with a single entry at the
14076 // top and a single exit at the bottom.
14077 // The point of exit cannot be a branch out of the structured block.
14078 // longjmp() and throw() must not violate the entry/exit criteria.
14079 CS->getCapturedDecl()->setNothrow();
14080 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14081 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14082 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14083 // 1.2.2 OpenMP Language Terminology
14084 // Structured block - An executable statement with a single entry at the
14085 // top and a single exit at the bottom.
14086 // The point of exit cannot be a branch out of the structured block.
14087 // longjmp() and throw() must not violate the entry/exit criteria.
14088 CS->getCapturedDecl()->setNothrow();
14089 }
14090
14091 OMPLoopBasedDirective::HelperExprs B;
14092 // In presence of clause 'collapse' with number of loops, it will define the
14093 // nested loops number.
14094 unsigned NestedLoopCount =
14095 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14096 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14097 VarsWithImplicitDSA, B);
14098 if (NestedLoopCount == 0)
14099 return StmtError();
14100
14101 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", 14102, __extension__ __PRETTY_FUNCTION__
))
14102 "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", 14102, __extension__ __PRETTY_FUNCTION__
))
;
14103
14104 if (!CurContext->isDependentContext()) {
14105 // Finalize the clauses that need pre-built expressions for CodeGen.
14106 for (OMPClause *C : Clauses) {
14107 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14108 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14109 B.NumIterations, *this, CurScope,
14110 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14111 return StmtError();
14112 }
14113 }
14114
14115 if (checkSimdlenSafelenSpecified(*this, Clauses))
14116 return StmtError();
14117
14118 setFunctionHasBranchProtectedScope();
14119 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14120 NestedLoopCount, Clauses, AStmt, B);
14121}
14122
14123StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14124 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14125 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14126 if (!AStmt)
14127 return StmtError();
14128
14129 auto *CS = cast<CapturedStmt>(AStmt);
14130 // 1.2.2 OpenMP Language Terminology
14131 // Structured block - An executable statement with a single entry at the
14132 // top and a single exit at the bottom.
14133 // The point of exit cannot be a branch out of the structured block.
14134 // longjmp() and throw() must not violate the entry/exit criteria.
14135 CS->getCapturedDecl()->setNothrow();
14136 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14137 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14138 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14139 // 1.2.2 OpenMP Language Terminology
14140 // Structured block - An executable statement with a single entry at the
14141 // top and a single exit at the bottom.
14142 // The point of exit cannot be a branch out of the structured block.
14143 // longjmp() and throw() must not violate the entry/exit criteria.
14144 CS->getCapturedDecl()->setNothrow();
14145 }
14146
14147 OMPLoopBasedDirective::HelperExprs B;
14148 // In presence of clause 'collapse' with number of loops, it will
14149 // define the nested loops number.
14150 unsigned NestedLoopCount =
14151 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14152 nullptr /*ordered not a clause on distribute*/, CS, *this,
14153 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
14154 if (NestedLoopCount == 0)
14155 return StmtError();
14156
14157 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", 14158, __extension__ __PRETTY_FUNCTION__
))
14158 "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", 14158, __extension__ __PRETTY_FUNCTION__
))
;
14159
14160 setFunctionHasBranchProtectedScope();
14161
14162 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
14163
14164 return OMPTeamsDistributeDirective::Create(
14165 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14166}
14167
14168StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14169 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14170 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14171 if (!AStmt)
14172 return StmtError();
14173
14174 auto *CS = cast<CapturedStmt>(AStmt);
14175 // 1.2.2 OpenMP Language Terminology
14176 // Structured block - An executable statement with a single entry at the
14177 // top and a single exit at the bottom.
14178 // The point of exit cannot be a branch out of the structured block.
14179 // longjmp() and throw() must not violate the entry/exit criteria.
14180 CS->getCapturedDecl()->setNothrow();
14181 for (int ThisCaptureLevel =
14182 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14183 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14184 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14185 // 1.2.2 OpenMP Language Terminology
14186 // Structured block - An executable statement with a single entry at the
14187 // top and a single exit at the bottom.
14188 // The point of exit cannot be a branch out of the structured block.
14189 // longjmp() and throw() must not violate the entry/exit criteria.
14190 CS->getCapturedDecl()->setNothrow();
14191 }
14192
14193 OMPLoopBasedDirective::HelperExprs B;
14194 // In presence of clause 'collapse' with number of loops, it will
14195 // define the nested loops number.
14196 unsigned NestedLoopCount = checkOpenMPLoop(
14197 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14198 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14199 VarsWithImplicitDSA, B);
14200
14201 if (NestedLoopCount == 0)
14202 return StmtError();
14203
14204 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", 14205, __extension__ __PRETTY_FUNCTION__
))
14205 "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", 14205, __extension__ __PRETTY_FUNCTION__
))
;
14206
14207 if (!CurContext->isDependentContext()) {
14208 // Finalize the clauses that need pre-built expressions for CodeGen.
14209 for (OMPClause *C : Clauses) {
14210 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14211 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14212 B.NumIterations, *this, CurScope,
14213 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14214 return StmtError();
14215 }
14216 }
14217
14218 if (checkSimdlenSafelenSpecified(*this, Clauses))
14219 return StmtError();
14220
14221 setFunctionHasBranchProtectedScope();
14222
14223 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
14224
14225 return OMPTeamsDistributeSimdDirective::Create(
14226 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14227}
14228
14229StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14230 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14231 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14232 if (!AStmt)
14233 return StmtError();
14234
14235 auto *CS = cast<CapturedStmt>(AStmt);
14236 // 1.2.2 OpenMP Language Terminology
14237 // Structured block - An executable statement with a single entry at the
14238 // top and a single exit at the bottom.
14239 // The point of exit cannot be a branch out of the structured block.
14240 // longjmp() and throw() must not violate the entry/exit criteria.
14241 CS->getCapturedDecl()->setNothrow();
14242
14243 for (int ThisCaptureLevel =
14244 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14245 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14246 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14247 // 1.2.2 OpenMP Language Terminology
14248 // Structured block - An executable statement with a single entry at the
14249 // top and a single exit at the bottom.
14250 // The point of exit cannot be a branch out of the structured block.
14251 // longjmp() and throw() must not violate the entry/exit criteria.
14252 CS->getCapturedDecl()->setNothrow();
14253 }
14254
14255 OMPLoopBasedDirective::HelperExprs B;
14256 // In presence of clause 'collapse' with number of loops, it will
14257 // define the nested loops number.
14258 unsigned NestedLoopCount = checkOpenMPLoop(
14259 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14260 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14261 VarsWithImplicitDSA, B);
14262
14263 if (NestedLoopCount == 0)
14264 return StmtError();
14265
14266 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", 14267, __extension__ __PRETTY_FUNCTION__
))
14267 "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", 14267, __extension__ __PRETTY_FUNCTION__
))
;
14268
14269 if (!CurContext->isDependentContext()) {
14270 // Finalize the clauses that need pre-built expressions for CodeGen.
14271 for (OMPClause *C : Clauses) {
14272 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14273 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14274 B.NumIterations, *this, CurScope,
14275 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14276 return StmtError();
14277 }
14278 }
14279
14280 if (checkSimdlenSafelenSpecified(*this, Clauses))
14281 return StmtError();
14282
14283 setFunctionHasBranchProtectedScope();
14284
14285 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
14286
14287 return OMPTeamsDistributeParallelForSimdDirective::Create(
14288 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14289}
14290
14291StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14292 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14293 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14294 if (!AStmt)
14295 return StmtError();
14296
14297 auto *CS = cast<CapturedStmt>(AStmt);
14298 // 1.2.2 OpenMP Language Terminology
14299 // Structured block - An executable statement with a single entry at the
14300 // top and a single exit at the bottom.
14301 // The point of exit cannot be a branch out of the structured block.
14302 // longjmp() and throw() must not violate the entry/exit criteria.
14303 CS->getCapturedDecl()->setNothrow();
14304
14305 for (int ThisCaptureLevel =
14306 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14307 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14308 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14309 // 1.2.2 OpenMP Language Terminology
14310 // Structured block - An executable statement with a single entry at the
14311 // top and a single exit at the bottom.
14312 // The point of exit cannot be a branch out of the structured block.
14313 // longjmp() and throw() must not violate the entry/exit criteria.
14314 CS->getCapturedDecl()->setNothrow();
14315 }
14316
14317 OMPLoopBasedDirective::HelperExprs B;
14318 // In presence of clause 'collapse' with number of loops, it will
14319 // define the nested loops number.
14320 unsigned NestedLoopCount = checkOpenMPLoop(
14321 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14322 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14323 VarsWithImplicitDSA, B);
14324
14325 if (NestedLoopCount == 0)
14326 return StmtError();
14327
14328 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", 14329, __extension__ __PRETTY_FUNCTION__
))
14329 "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", 14329, __extension__ __PRETTY_FUNCTION__
))
;
14330
14331 setFunctionHasBranchProtectedScope();
14332
14333 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
14334
14335 return OMPTeamsDistributeParallelForDirective::Create(
14336 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14337 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
14338}
14339
14340StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14341 Stmt *AStmt,
14342 SourceLocation StartLoc,
14343 SourceLocation EndLoc) {
14344 if (!AStmt)
14345 return StmtError();
14346
14347 auto *CS = cast<CapturedStmt>(AStmt);
14348 // 1.2.2 OpenMP Language Terminology
14349 // Structured block - An executable statement with a single entry at the
14350 // top and a single exit at the bottom.
14351 // The point of exit cannot be a branch out of the structured block.
14352 // longjmp() and throw() must not violate the entry/exit criteria.
14353 CS->getCapturedDecl()->setNothrow();
14354
14355 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14356 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14357 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14358 // 1.2.2 OpenMP Language Terminology
14359 // Structured block - An executable statement with a single entry at the
14360 // top and a single exit at the bottom.
14361 // The point of exit cannot be a branch out of the structured block.
14362 // longjmp() and throw() must not violate the entry/exit criteria.
14363 CS->getCapturedDecl()->setNothrow();
14364 }
14365 setFunctionHasBranchProtectedScope();
14366
14367 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14368 AStmt);
14369}
14370
14371StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14372 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14373 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14374 if (!AStmt)
14375 return StmtError();
14376
14377 auto *CS = cast<CapturedStmt>(AStmt);
14378 // 1.2.2 OpenMP Language Terminology
14379 // Structured block - An executable statement with a single entry at the
14380 // top and a single exit at the bottom.
14381 // The point of exit cannot be a branch out of the structured block.
14382 // longjmp() and throw() must not violate the entry/exit criteria.
14383 CS->getCapturedDecl()->setNothrow();
14384 for (int ThisCaptureLevel =
14385 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14386 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14387 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14388 // 1.2.2 OpenMP Language Terminology
14389 // Structured block - An executable statement with a single entry at the
14390 // top and a single exit at the bottom.
14391 // The point of exit cannot be a branch out of the structured block.
14392 // longjmp() and throw() must not violate the entry/exit criteria.
14393 CS->getCapturedDecl()->setNothrow();
14394 }
14395
14396 OMPLoopBasedDirective::HelperExprs B;
14397 // In presence of clause 'collapse' with number of loops, it will
14398 // define the nested loops number.
14399 unsigned NestedLoopCount = checkOpenMPLoop(
14400 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14401 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14402 VarsWithImplicitDSA, B);
14403 if (NestedLoopCount == 0)
14404 return StmtError();
14405
14406 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", 14407, __extension__ __PRETTY_FUNCTION__
))
14407 "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", 14407, __extension__ __PRETTY_FUNCTION__
))
;
14408
14409 setFunctionHasBranchProtectedScope();
14410 return OMPTargetTeamsDistributeDirective::Create(
14411 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14412}
14413
14414StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14415 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14416 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14417 if (!AStmt)
14418 return StmtError();
14419
14420 auto *CS = cast<CapturedStmt>(AStmt);
14421 // 1.2.2 OpenMP Language Terminology
14422 // Structured block - An executable statement with a single entry at the
14423 // top and a single exit at the bottom.
14424 // The point of exit cannot be a branch out of the structured block.
14425 // longjmp() and throw() must not violate the entry/exit criteria.
14426 CS->getCapturedDecl()->setNothrow();
14427 for (int ThisCaptureLevel =
14428 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14429 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14430 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14431 // 1.2.2 OpenMP Language Terminology
14432 // Structured block - An executable statement with a single entry at the
14433 // top and a single exit at the bottom.
14434 // The point of exit cannot be a branch out of the structured block.
14435 // longjmp() and throw() must not violate the entry/exit criteria.
14436 CS->getCapturedDecl()->setNothrow();
14437 }
14438
14439 OMPLoopBasedDirective::HelperExprs B;
14440 // In presence of clause 'collapse' with number of loops, it will
14441 // define the nested loops number.
14442 unsigned NestedLoopCount = checkOpenMPLoop(
14443 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14444 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14445 VarsWithImplicitDSA, B);
14446 if (NestedLoopCount == 0)
14447 return StmtError();
14448
14449 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", 14450, __extension__ __PRETTY_FUNCTION__
))
14450 "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", 14450, __extension__ __PRETTY_FUNCTION__
))
;
14451
14452 if (!CurContext->isDependentContext()) {
14453 // Finalize the clauses that need pre-built expressions for CodeGen.
14454 for (OMPClause *C : Clauses) {
14455 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14456 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14457 B.NumIterations, *this, CurScope,
14458 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14459 return StmtError();
14460 }
14461 }
14462
14463 setFunctionHasBranchProtectedScope();
14464 return OMPTargetTeamsDistributeParallelForDirective::Create(
14465 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14466 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
14467}
14468
14469StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14470 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14471 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14472 if (!AStmt)
14473 return StmtError();
14474
14475 auto *CS = cast<CapturedStmt>(AStmt);
14476 // 1.2.2 OpenMP Language Terminology
14477 // Structured block - An executable statement with a single entry at the
14478 // top and a single exit at the bottom.
14479 // The point of exit cannot be a branch out of the structured block.
14480 // longjmp() and throw() must not violate the entry/exit criteria.
14481 CS->getCapturedDecl()->setNothrow();
14482 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14483 OMPD_target_teams_distribute_parallel_for_simd);
14484 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14485 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14486 // 1.2.2 OpenMP Language Terminology
14487 // Structured block - An executable statement with a single entry at the
14488 // top and a single exit at the bottom.
14489 // The point of exit cannot be a branch out of the structured block.
14490 // longjmp() and throw() must not violate the entry/exit criteria.
14491 CS->getCapturedDecl()->setNothrow();
14492 }
14493
14494 OMPLoopBasedDirective::HelperExprs B;
14495 // In presence of clause 'collapse' with number of loops, it will
14496 // define the nested loops number.
14497 unsigned NestedLoopCount =
14498 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14499 getCollapseNumberExpr(Clauses),
14500 nullptr /*ordered not a clause on distribute*/, CS, *this,
14501 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
14502 if (NestedLoopCount == 0)
14503 return StmtError();
14504
14505 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", 14507, __extension__ __PRETTY_FUNCTION__
))
14506 "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", 14507, __extension__ __PRETTY_FUNCTION__
))
14507 "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", 14507, __extension__ __PRETTY_FUNCTION__
))
;
14508
14509 if (!CurContext->isDependentContext()) {
14510 // Finalize the clauses that need pre-built expressions for CodeGen.
14511 for (OMPClause *C : Clauses) {
14512 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14513 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14514 B.NumIterations, *this, CurScope,
14515 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14516 return StmtError();
14517 }
14518 }
14519
14520 if (checkSimdlenSafelenSpecified(*this, Clauses))
14521 return StmtError();
14522
14523 setFunctionHasBranchProtectedScope();
14524 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14525 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14526}
14527
14528StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14529 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14530 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14531 if (!AStmt)
14532 return StmtError();
14533
14534 auto *CS = cast<CapturedStmt>(AStmt);
14535 // 1.2.2 OpenMP Language Terminology
14536 // Structured block - An executable statement with a single entry at the
14537 // top and a single exit at the bottom.
14538 // The point of exit cannot be a branch out of the structured block.
14539 // longjmp() and throw() must not violate the entry/exit criteria.
14540 CS->getCapturedDecl()->setNothrow();
14541 for (int ThisCaptureLevel =
14542 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14543 ThisCaptureLevel > 1; --ThisCaptureLevel) {
14544 CS = cast<CapturedStmt>(CS->getCapturedStmt());
14545 // 1.2.2 OpenMP Language Terminology
14546 // Structured block - An executable statement with a single entry at the
14547 // top and a single exit at the bottom.
14548 // The point of exit cannot be a branch out of the structured block.
14549 // longjmp() and throw() must not violate the entry/exit criteria.
14550 CS->getCapturedDecl()->setNothrow();
14551 }
14552
14553 OMPLoopBasedDirective::HelperExprs B;
14554 // In presence of clause 'collapse' with number of loops, it will
14555 // define the nested loops number.
14556 unsigned NestedLoopCount = checkOpenMPLoop(
14557 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14558 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14559 VarsWithImplicitDSA, B);
14560 if (NestedLoopCount == 0)
14561 return StmtError();
14562
14563 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", 14564, __extension__ __PRETTY_FUNCTION__
))
14564 "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", 14564, __extension__ __PRETTY_FUNCTION__
))
;
14565
14566 if (!CurContext->isDependentContext()) {
14567 // Finalize the clauses that need pre-built expressions for CodeGen.
14568 for (OMPClause *C : Clauses) {
14569 if (auto *LC = dyn_cast<OMPLinearClause>(C))
14570 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14571 B.NumIterations, *this, CurScope,
14572 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
14573 return StmtError();
14574 }
14575 }
14576
14577 if (checkSimdlenSafelenSpecified(*this, Clauses))
14578 return StmtError();
14579
14580 setFunctionHasBranchProtectedScope();
14581 return OMPTargetTeamsDistributeSimdDirective::Create(
14582 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14583}
14584
14585bool Sema::checkTransformableLoopNest(
14586 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14587 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14588 Stmt *&Body,
14589 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14590 &OriginalInits) {
14591 OriginalInits.emplace_back();
14592 bool Result = OMPLoopBasedDirective::doForAllLoops(
14593 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14594 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14595 Stmt *CurStmt) {
14596 VarsWithInheritedDSAType TmpDSA;
14597 unsigned SingleNumLoops =
14598 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
14599 TmpDSA, LoopHelpers[Cnt]);
14600 if (SingleNumLoops == 0)
14601 return true;
14602 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", 14602, __extension__ __PRETTY_FUNCTION__
))
;
14603 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14604 OriginalInits.back().push_back(For->getInit());
14605 Body = For->getBody();
14606 } else {
14607 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", 14608, __extension__ __PRETTY_FUNCTION__
))
14608 "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", 14608, __extension__ __PRETTY_FUNCTION__
))
;
14609 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14610 OriginalInits.back().push_back(CXXFor->getBeginStmt());
14611 Body = CXXFor->getBody();
14612 }
14613 OriginalInits.emplace_back();
14614 return false;
14615 },
14616 [&OriginalInits](OMPLoopBasedDirective *Transform) {
14617 Stmt *DependentPreInits;
14618 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14619 DependentPreInits = Dir->getPreInits();
14620 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14621 DependentPreInits = Dir->getPreInits();
14622 else
14623 llvm_unreachable("Unhandled loop transformation")::llvm::llvm_unreachable_internal("Unhandled loop transformation"
, "clang/lib/Sema/SemaOpenMP.cpp", 14623)
;
14624 if (!DependentPreInits)
14625 return;
14626 llvm::append_range(OriginalInits.back(),
14627 cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14628 });
14629 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", 14629, __extension__ __PRETTY_FUNCTION__
))
;
14630 OriginalInits.pop_back();
14631 return Result;
14632}
14633
14634StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14635 Stmt *AStmt, SourceLocation StartLoc,
14636 SourceLocation EndLoc) {
14637 auto SizesClauses =
14638 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14639 if (SizesClauses.empty()) {
14640 // A missing 'sizes' clause is already reported by the parser.
14641 return StmtError();
14642 }
14643 const OMPSizesClause *SizesClause = *SizesClauses.begin();
14644 unsigned NumLoops = SizesClause->getNumSizes();
14645
14646 // Empty statement should only be possible if there already was an error.
14647 if (!AStmt)
14648 return StmtError();
14649
14650 // Verify and diagnose loop nest.
14651 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14652 Stmt *Body = nullptr;
14653 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14654 OriginalInits;
14655 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14656 OriginalInits))
14657 return StmtError();
14658
14659 // Delay tiling to when template is completely instantiated.
14660 if (CurContext->isDependentContext())
14661 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14662 NumLoops, AStmt, nullptr, nullptr);
14663
14664 SmallVector<Decl *, 4> PreInits;
14665
14666 // Create iteration variables for the generated loops.
14667 SmallVector<VarDecl *, 4> FloorIndVars;
14668 SmallVector<VarDecl *, 4> TileIndVars;
14669 FloorIndVars.resize(NumLoops);
14670 TileIndVars.resize(NumLoops);
14671 for (unsigned I = 0; I < NumLoops; ++I) {
14672 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14673
14674 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", 14675, __extension__ __PRETTY_FUNCTION__
))
14675 "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", 14675, __extension__ __PRETTY_FUNCTION__
))
;
14676 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14677 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14678 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14679 QualType CntTy = IterVarRef->getType();
14680
14681 // Iteration variable for the floor (i.e. outer) loop.
14682 {
14683 std::string FloorCntName =
14684 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14685 VarDecl *FloorCntDecl =
14686 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14687 FloorIndVars[I] = FloorCntDecl;
14688 }
14689
14690 // Iteration variable for the tile (i.e. inner) loop.
14691 {
14692 std::string TileCntName =
14693 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14694
14695 // Reuse the iteration variable created by checkOpenMPLoop. It is also
14696 // used by the expressions to derive the original iteration variable's
14697 // value from the logical iteration number.
14698 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14699 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14700 TileIndVars[I] = TileCntDecl;
14701 }
14702 for (auto &P : OriginalInits[I]) {
14703 if (auto *D = P.dyn_cast<Decl *>())
14704 PreInits.push_back(D);
14705 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14706 PreInits.append(PI->decl_begin(), PI->decl_end());
14707 }
14708 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14709 PreInits.append(PI->decl_begin(), PI->decl_end());
14710 // Gather declarations for the data members used as counters.
14711 for (Expr *CounterRef : LoopHelper.Counters) {
14712 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14713 if (isa<OMPCapturedExprDecl>(CounterDecl))
14714 PreInits.push_back(CounterDecl);
14715 }
14716 }
14717
14718 // Once the original iteration values are set, append the innermost body.
14719 Stmt *Inner = Body;
14720
14721 // Create tile loops from the inside to the outside.
14722 for (int I = NumLoops - 1; I >= 0; --I) {
14723 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14724 Expr *NumIterations = LoopHelper.NumIterations;
14725 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14726 QualType CntTy = OrigCntVar->getType();
14727 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14728 Scope *CurScope = getCurScope();
14729
14730 // Commonly used variables.
14731 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14732 OrigCntVar->getExprLoc());
14733 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14734 OrigCntVar->getExprLoc());
14735
14736 // For init-statement: auto .tile.iv = .floor.iv
14737 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14738 /*DirectInit=*/false);
14739 Decl *CounterDecl = TileIndVars[I];
14740 StmtResult InitStmt = new (Context)
14741 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14742 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14743 if (!InitStmt.isUsable())
14744 return StmtError();
14745
14746 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14747 // NumIterations)
14748 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14749 BO_Add, FloorIV, DimTileSize);
14750 if (!EndOfTile.isUsable())
14751 return StmtError();
14752 ExprResult IsPartialTile =
14753 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14754 NumIterations, EndOfTile.get());
14755 if (!IsPartialTile.isUsable())
14756 return StmtError();
14757 ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14758 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14759 IsPartialTile.get(), NumIterations, EndOfTile.get());
14760 if (!MinTileAndIterSpace.isUsable())
14761 return StmtError();
14762 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14763 BO_LT, TileIV, MinTileAndIterSpace.get());
14764 if (!CondExpr.isUsable())
14765 return StmtError();
14766
14767 // For incr-statement: ++.tile.iv
14768 ExprResult IncrStmt =
14769 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14770 if (!IncrStmt.isUsable())
14771 return StmtError();
14772
14773 // Statements to set the original iteration variable's value from the
14774 // logical iteration number.
14775 // Generated for loop is:
14776 // Original_for_init;
14777 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14778 // NumIterations); ++.tile.iv) {
14779 // Original_Body;
14780 // Original_counter_update;
14781 // }
14782 // FIXME: If the innermost body is an loop itself, inserting these
14783 // statements stops it being recognized as a perfectly nested loop (e.g.
14784 // for applying tiling again). If this is the case, sink the expressions
14785 // further into the inner loop.
14786 SmallVector<Stmt *, 4> BodyParts;
14787 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14788 BodyParts.push_back(Inner);
14789 Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
14790 Inner->getBeginLoc(), Inner->getEndLoc());
14791 Inner = new (Context)
14792 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14793 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14794 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14795 }
14796
14797 // Create floor loops from the inside to the outside.
14798 for (int I = NumLoops - 1; I >= 0; --I) {
14799 auto &LoopHelper = LoopHelpers[I];
14800 Expr *NumIterations = LoopHelper.NumIterations;
14801 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14802 QualType CntTy = OrigCntVar->getType();
14803 Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14804 Scope *CurScope = getCurScope();
14805
14806 // Commonly used variables.
14807 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14808 OrigCntVar->getExprLoc());
14809
14810 // For init-statement: auto .floor.iv = 0
14811 AddInitializerToDecl(
14812 FloorIndVars[I],
14813 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14814 /*DirectInit=*/false);
14815 Decl *CounterDecl = FloorIndVars[I];
14816 StmtResult InitStmt = new (Context)
14817 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14818 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14819 if (!InitStmt.isUsable())
14820 return StmtError();
14821
14822 // For cond-expression: .floor.iv < NumIterations
14823 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14824 BO_LT, FloorIV, NumIterations);
14825 if (!CondExpr.isUsable())
14826 return StmtError();
14827
14828 // For incr-statement: .floor.iv += DimTileSize
14829 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14830 BO_AddAssign, FloorIV, DimTileSize);
14831 if (!IncrStmt.isUsable())
14832 return StmtError();
14833
14834 Inner = new (Context)
14835 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14836 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14837 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14838 }
14839
14840 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14841 AStmt, Inner,
14842 buildPreInits(Context, PreInits));
14843}
14844
14845StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
14846 Stmt *AStmt,
14847 SourceLocation StartLoc,
14848 SourceLocation EndLoc) {
14849 // Empty statement should only be possible if there already was an error.
14850 if (!AStmt)
14851 return StmtError();
14852
14853 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14854 return StmtError();
14855
14856 const OMPFullClause *FullClause =
14857 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14858 const OMPPartialClause *PartialClause =
14859 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14860 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", 14861, __extension__ __PRETTY_FUNCTION__
))
14861 "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", 14861, __extension__ __PRETTY_FUNCTION__
))
;
14862
14863 constexpr unsigned NumLoops = 1;
14864 Stmt *Body = nullptr;
14865 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14866 NumLoops);
14867 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
14868 OriginalInits;
14869 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14870 Body, OriginalInits))
14871 return StmtError();
14872
14873 unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14874
14875 // Delay unrolling to when template is completely instantiated.
14876 if (CurContext->isDependentContext())
14877 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14878 NumGeneratedLoops, nullptr, nullptr);
14879
14880 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14881
14882 if (FullClause) {
14883 if (!VerifyPositiveIntegerConstantInClause(
14884 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14885 /*SuppressExprDiags=*/true)
14886 .isUsable()) {
14887 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14888 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14889 << "#pragma omp unroll full";
14890 return StmtError();
14891 }
14892 }
14893
14894 // The generated loop may only be passed to other loop-associated directive
14895 // when a partial clause is specified. Without the requirement it is
14896 // sufficient to generate loop unroll metadata at code-generation.
14897 if (NumGeneratedLoops == 0)
14898 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14899 NumGeneratedLoops, nullptr, nullptr);
14900
14901 // Otherwise, we need to provide a de-sugared/transformed AST that can be
14902 // associated with another loop directive.
14903 //
14904 // The canonical loop analysis return by checkTransformableLoopNest assumes
14905 // the following structure to be the same loop without transformations or
14906 // directives applied: \code OriginalInits; LoopHelper.PreInits;
14907 // LoopHelper.Counters;
14908 // for (; IV < LoopHelper.NumIterations; ++IV) {
14909 // LoopHelper.Updates;
14910 // Body;
14911 // }
14912 // \endcode
14913 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14914 // and referenced by LoopHelper.IterationVarRef.
14915 //
14916 // The unrolling directive transforms this into the following loop:
14917 // \code
14918 // OriginalInits; \
14919 // LoopHelper.PreInits; > NewPreInits
14920 // LoopHelper.Counters; /
14921 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14922 // #pragma clang loop unroll_count(Factor)
14923 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14924 // {
14925 // LoopHelper.Updates;
14926 // Body;
14927 // }
14928 // }
14929 // \endcode
14930 // where UIV is a new logical iteration counter. IV must be the same VarDecl
14931 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14932 // references it. If the partially unrolled loop is associated with another
14933 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14934 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14935 // OpenMP canonical loop. The inner loop is not an associable canonical loop
14936 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14937 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14938 // property of the OMPLoopBasedDirective instead of statements in
14939 // CompoundStatement. This is to allow the loop to become a non-outermost loop
14940 // of a canonical loop nest where these PreInits are emitted before the
14941 // outermost directive.
14942
14943 // Determine the PreInit declarations.
14944 SmallVector<Decl *, 4> PreInits;
14945 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", 14946, __extension__ __PRETTY_FUNCTION__
))
14946 "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", 14946, __extension__ __PRETTY_FUNCTION__
))
;
14947 for (auto &P : OriginalInits[0]) {
14948 if (auto *D = P.dyn_cast<Decl *>())
14949 PreInits.push_back(D);
14950 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14951 PreInits.append(PI->decl_begin(), PI->decl_end());
14952 }
14953 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14954 PreInits.append(PI->decl_begin(), PI->decl_end());
14955 // Gather declarations for the data members used as counters.
14956 for (Expr *CounterRef : LoopHelper.Counters) {
14957 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14958 if (isa<OMPCapturedExprDecl>(CounterDecl))
14959 PreInits.push_back(CounterDecl);
14960 }
14961
14962 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14963 QualType IVTy = IterationVarRef->getType();
14964 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", 14965, __extension__ __PRETTY_FUNCTION__
))
14965 "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", 14965, __extension__ __PRETTY_FUNCTION__
))
;
14966 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14967
14968 // Determine the unroll factor.
14969 uint64_t Factor;
14970 SourceLocation FactorLoc;
14971 if (Expr *FactorVal = PartialClause->getFactor()) {
14972 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
14973 FactorLoc = FactorVal->getExprLoc();
14974 } else {
14975 // TODO: Use a better profitability model.
14976 Factor = 2;
14977 }
14978 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", 14978, __extension__ __PRETTY_FUNCTION__
))
;
14979 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14980 return IntegerLiteral::Create(
14981 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
14982 FactorLoc);
14983 };
14984
14985 // Iteration variable SourceLocations.
14986 SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14987 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14988 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14989
14990 // Internal variable names.
14991 std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14992 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14993 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14994 std::string InnerTripCountName =
14995 (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14996
14997 // Create the iteration variable for the unrolled loop.
14998 VarDecl *OuterIVDecl =
14999 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15000 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15001 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15002 };
15003
15004 // Iteration variable for the inner loop: Reuse the iteration variable created
15005 // by checkOpenMPLoop.
15006 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15007 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15008 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15009 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15010 };
15011
15012 // Make a copy of the NumIterations expression for each use: By the AST
15013 // constraints, every expression object in a DeclContext must be unique.
15014 CaptureVars CopyTransformer(*this);
15015 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15016 return AssertSuccess(
15017 CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15018 };
15019
15020 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15021 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15022 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15023 StmtResult InnerInit = new (Context)
15024 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15025 if (!InnerInit.isUsable())
15026 return StmtError();
15027
15028 // Inner For cond-expression:
15029 // \code
15030 // .unroll_inner.iv < .unrolled.iv + Factor &&
15031 // .unroll_inner.iv < NumIterations
15032 // \endcode
15033 // This conjunction of two conditions allows ScalarEvolution to derive the
15034 // maximum trip count of the inner loop.
15035 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15036 BO_Add, MakeOuterRef(), MakeFactorExpr());
15037 if (!EndOfTile.isUsable())
15038 return StmtError();
15039 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15040 BO_LT, MakeInnerRef(), EndOfTile.get());
15041 if (!InnerCond1.isUsable())
15042 return StmtError();
15043 ExprResult InnerCond2 =
15044 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15045 MakeNumIterations());
15046 if (!InnerCond2.isUsable())
15047 return StmtError();
15048 ExprResult InnerCond =
15049 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15050 InnerCond1.get(), InnerCond2.get());
15051 if (!InnerCond.isUsable())
15052 return StmtError();
15053
15054 // Inner For incr-statement: ++.unroll_inner.iv
15055 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15056 UO_PreInc, MakeInnerRef());
15057 if (!InnerIncr.isUsable())
15058 return StmtError();
15059
15060 // Inner For statement.
15061 SmallVector<Stmt *> InnerBodyStmts;
15062 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15063 InnerBodyStmts.push_back(Body);
15064 CompoundStmt *InnerBody =
15065 CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15066 Body->getBeginLoc(), Body->getEndLoc());
15067 ForStmt *InnerFor = new (Context)
15068 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15069 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15070 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15071
15072 // Unroll metadata for the inner loop.
15073 // This needs to take into account the remainder portion of the unrolled loop,
15074 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15075 // supports multiple loop exits. Instead, unroll using a factor equivalent to
15076 // the maximum trip count, which will also generate a remainder loop. Just
15077 // `unroll(enable)` (which could have been useful if the user has not
15078 // specified a concrete factor; even though the outer loop cannot be
15079 // influenced anymore, would avoid more code bloat than necessary) will refuse
15080 // the loop because "Won't unroll; remainder loop could not be generated when
15081 // assuming runtime trip count". Even if it did work, it must not choose a
15082 // larger unroll factor than the maximum loop length, or it would always just
15083 // execute the remainder loop.
15084 LoopHintAttr *UnrollHintAttr =
15085 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15086 LoopHintAttr::Numeric, MakeFactorExpr());
15087 AttributedStmt *InnerUnrolled =
15088 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15089
15090 // Outer For init-statement: auto .unrolled.iv = 0
15091 AddInitializerToDecl(
15092 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15093 /*DirectInit=*/false);
15094 StmtResult OuterInit = new (Context)
15095 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15096 if (!OuterInit.isUsable())
15097 return StmtError();
15098
15099 // Outer For cond-expression: .unrolled.iv < NumIterations
15100 ExprResult OuterConde =
15101 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15102 MakeNumIterations());
15103 if (!OuterConde.isUsable())
15104 return StmtError();
15105
15106 // Outer For incr-statement: .unrolled.iv += Factor
15107 ExprResult OuterIncr =
15108 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15109 MakeOuterRef(), MakeFactorExpr());
15110 if (!OuterIncr.isUsable())
15111 return StmtError();
15112
15113 // Outer For statement.
15114 ForStmt *OuterFor = new (Context)
15115 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15116 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15117 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15118
15119 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15120 NumGeneratedLoops, OuterFor,
15121 buildPreInits(Context, PreInits));
15122}
15123
15124OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15125 SourceLocation StartLoc,
15126 SourceLocation LParenLoc,
15127 SourceLocation EndLoc) {
15128 OMPClause *Res = nullptr;
15129 switch (Kind) {
15130 case OMPC_final:
15131 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15132 break;
15133 case OMPC_num_threads:
15134 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15135 break;
15136 case OMPC_safelen:
15137 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15138 break;
15139 case OMPC_simdlen:
15140 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15141 break;
15142 case OMPC_allocator:
15143 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15144 break;
15145 case OMPC_collapse:
15146 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15147 break;
15148 case OMPC_ordered:
15149 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15150 break;
15151 case OMPC_num_teams:
15152 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15153 break;
15154 case OMPC_thread_limit:
15155 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15156 break;
15157 case OMPC_priority:
15158 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15159 break;
15160 case OMPC_hint:
15161 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15162 break;
15163 case OMPC_depobj:
15164 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15165 break;
15166 case OMPC_detach:
15167 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15168 break;
15169 case OMPC_novariants:
15170 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15171 break;
15172 case OMPC_nocontext:
15173 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15174 break;
15175 case OMPC_filter:
15176 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15177 break;
15178 case OMPC_partial:
15179 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15180 break;
15181 case OMPC_message:
15182 Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15183 break;
15184 case OMPC_align:
15185 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15186 break;
15187 case OMPC_grainsize:
15188 case OMPC_num_tasks:
15189 case OMPC_device:
15190 case OMPC_if:
15191 case OMPC_default:
15192 case OMPC_proc_bind:
15193 case OMPC_schedule:
15194 case OMPC_private:
15195 case OMPC_firstprivate:
15196 case OMPC_lastprivate:
15197 case OMPC_shared:
15198 case OMPC_reduction:
15199 case OMPC_task_reduction:
15200 case OMPC_in_reduction:
15201 case OMPC_linear:
15202 case OMPC_aligned:
15203 case OMPC_copyin:
15204 case OMPC_copyprivate:
15205 case OMPC_nowait:
15206 case OMPC_untied:
15207 case OMPC_mergeable:
15208 case OMPC_threadprivate:
15209 case OMPC_sizes:
15210 case OMPC_allocate:
15211 case OMPC_flush:
15212 case OMPC_read:
15213 case OMPC_write:
15214 case OMPC_update:
15215 case OMPC_capture:
15216 case OMPC_compare:
15217 case OMPC_seq_cst:
15218 case OMPC_acq_rel:
15219 case OMPC_acquire:
15220 case OMPC_release:
15221 case OMPC_relaxed:
15222 case OMPC_depend:
15223 case OMPC_threads:
15224 case OMPC_simd:
15225 case OMPC_map:
15226 case OMPC_nogroup:
15227 case OMPC_dist_schedule:
15228 case OMPC_defaultmap:
15229 case OMPC_unknown:
15230 case OMPC_uniform:
15231 case OMPC_to:
15232 case OMPC_from:
15233 case OMPC_use_device_ptr:
15234 case OMPC_use_device_addr:
15235 case OMPC_is_device_ptr:
15236 case OMPC_unified_address:
15237 case OMPC_unified_shared_memory:
15238 case OMPC_reverse_offload:
15239 case OMPC_dynamic_allocators:
15240 case OMPC_atomic_default_mem_order:
15241 case OMPC_device_type:
15242 case OMPC_match:
15243 case OMPC_nontemporal:
15244 case OMPC_order:
15245 case OMPC_at:
15246 case OMPC_severity:
15247 case OMPC_destroy:
15248 case OMPC_inclusive:
15249 case OMPC_exclusive:
15250 case OMPC_uses_allocators:
15251 case OMPC_affinity:
15252 case OMPC_when:
15253 case OMPC_bind:
15254 default:
15255 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 15255)
;
15256 }
15257 return Res;
15258}
15259
15260// An OpenMP directive such as 'target parallel' has two captured regions:
15261// for the 'target' and 'parallel' respectively. This function returns
15262// the region in which to capture expressions associated with a clause.
15263// A return value of OMPD_unknown signifies that the expression should not
15264// be captured.
15265static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15266 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15267 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15268 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15269 switch (CKind) {
15270 case OMPC_if:
15271 switch (DKind) {
15272 case OMPD_target_parallel_for_simd:
15273 if (OpenMPVersion >= 50 &&
15274 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15275 CaptureRegion = OMPD_parallel;
15276 break;
15277 }
15278 [[fallthrough]];
15279 case OMPD_target_parallel:
15280 case OMPD_target_parallel_for:
15281 case OMPD_target_parallel_loop:
15282 // If this clause applies to the nested 'parallel' region, capture within
15283 // the 'target' region, otherwise do not capture.
15284 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15285 CaptureRegion = OMPD_target;
15286 break;
15287 case OMPD_target_teams_distribute_parallel_for_simd:
15288 if (OpenMPVersion >= 50 &&
15289 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15290 CaptureRegion = OMPD_parallel;
15291 break;
15292 }
15293 [[fallthrough]];
15294 case OMPD_target_teams_distribute_parallel_for:
15295 // If this clause applies to the nested 'parallel' region, capture within
15296 // the 'teams' region, otherwise do not capture.
15297 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15298 CaptureRegion = OMPD_teams;
15299 break;
15300 case OMPD_teams_distribute_parallel_for_simd:
15301 if (OpenMPVersion >= 50 &&
15302 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15303 CaptureRegion = OMPD_parallel;
15304 break;
15305 }
15306 [[fallthrough]];
15307 case OMPD_teams_distribute_parallel_for:
15308 CaptureRegion = OMPD_teams;
15309 break;
15310 case OMPD_target_update:
15311 case OMPD_target_enter_data:
15312 case OMPD_target_exit_data:
15313 CaptureRegion = OMPD_task;
15314 break;
15315 case OMPD_parallel_masked_taskloop:
15316 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15317 CaptureRegion = OMPD_parallel;
15318 break;
15319 case OMPD_parallel_master_taskloop:
15320 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15321 CaptureRegion = OMPD_parallel;
15322 break;
15323 case OMPD_parallel_masked_taskloop_simd:
15324 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15325 NameModifier == OMPD_taskloop) {
15326 CaptureRegion = OMPD_parallel;
15327 break;
15328 }
15329 if (OpenMPVersion <= 45)
15330 break;
15331 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15332 CaptureRegion = OMPD_taskloop;
15333 break;
15334 case OMPD_parallel_master_taskloop_simd:
15335 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15336 NameModifier == OMPD_taskloop) {
15337 CaptureRegion = OMPD_parallel;
15338 break;
15339 }
15340 if (OpenMPVersion <= 45)
15341 break;
15342 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15343 CaptureRegion = OMPD_taskloop;
15344 break;
15345 case OMPD_parallel_for_simd:
15346 if (OpenMPVersion <= 45)
15347 break;
15348 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15349 CaptureRegion = OMPD_parallel;
15350 break;
15351 case OMPD_taskloop_simd:
15352 case OMPD_master_taskloop_simd:
15353 case OMPD_masked_taskloop_simd:
15354 if (OpenMPVersion <= 45)
15355 break;
15356 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15357 CaptureRegion = OMPD_taskloop;
15358 break;
15359 case OMPD_distribute_parallel_for_simd:
15360 if (OpenMPVersion <= 45)
15361 break;
15362 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15363 CaptureRegion = OMPD_parallel;
15364 break;
15365 case OMPD_target_simd:
15366 if (OpenMPVersion >= 50 &&
15367 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15368 CaptureRegion = OMPD_target;
15369 break;
15370 case OMPD_teams_distribute_simd:
15371 case OMPD_target_teams_distribute_simd:
15372 if (OpenMPVersion >= 50 &&
15373 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15374 CaptureRegion = OMPD_teams;
15375 break;
15376 case OMPD_cancel:
15377 case OMPD_parallel:
15378 case OMPD_parallel_master:
15379 case OMPD_parallel_masked:
15380 case OMPD_parallel_sections:
15381 case OMPD_parallel_for:
15382 case OMPD_parallel_loop:
15383 case OMPD_target:
15384 case OMPD_target_teams:
15385 case OMPD_target_teams_distribute:
15386 case OMPD_target_teams_loop:
15387 case OMPD_distribute_parallel_for:
15388 case OMPD_task:
15389 case OMPD_taskloop:
15390 case OMPD_master_taskloop:
15391 case OMPD_masked_taskloop:
15392 case OMPD_target_data:
15393 case OMPD_simd:
15394 case OMPD_for_simd:
15395 case OMPD_distribute_simd:
15396 // Do not capture if-clause expressions.
15397 break;
15398 case OMPD_threadprivate:
15399 case OMPD_allocate:
15400 case OMPD_taskyield:
15401 case OMPD_error:
15402 case OMPD_barrier:
15403 case OMPD_taskwait:
15404 case OMPD_cancellation_point:
15405 case OMPD_flush:
15406 case OMPD_depobj:
15407 case OMPD_scan:
15408 case OMPD_declare_reduction:
15409 case OMPD_declare_mapper:
15410 case OMPD_declare_simd:
15411 case OMPD_declare_variant:
15412 case OMPD_begin_declare_variant:
15413 case OMPD_end_declare_variant:
15414 case OMPD_declare_target:
15415 case OMPD_end_declare_target:
15416 case OMPD_loop:
15417 case OMPD_teams_loop:
15418 case OMPD_teams:
15419 case OMPD_tile:
15420 case OMPD_unroll:
15421 case OMPD_for:
15422 case OMPD_sections:
15423 case OMPD_section:
15424 case OMPD_single:
15425 case OMPD_master:
15426 case OMPD_masked:
15427 case OMPD_critical:
15428 case OMPD_taskgroup:
15429 case OMPD_distribute:
15430 case OMPD_ordered:
15431 case OMPD_atomic:
15432 case OMPD_teams_distribute:
15433 case OMPD_requires:
15434 case OMPD_metadirective:
15435 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15435)
;
15436 case OMPD_unknown:
15437 default:
15438 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15438)
;
15439 }
15440 break;
15441 case OMPC_num_threads:
15442 switch (DKind) {
15443 case OMPD_target_parallel:
15444 case OMPD_target_parallel_for:
15445 case OMPD_target_parallel_for_simd:
15446 case OMPD_target_parallel_loop:
15447 CaptureRegion = OMPD_target;
15448 break;
15449 case OMPD_teams_distribute_parallel_for:
15450 case OMPD_teams_distribute_parallel_for_simd:
15451 case OMPD_target_teams_distribute_parallel_for:
15452 case OMPD_target_teams_distribute_parallel_for_simd:
15453 CaptureRegion = OMPD_teams;
15454 break;
15455 case OMPD_parallel:
15456 case OMPD_parallel_master:
15457 case OMPD_parallel_masked:
15458 case OMPD_parallel_sections:
15459 case OMPD_parallel_for:
15460 case OMPD_parallel_for_simd:
15461 case OMPD_parallel_loop:
15462 case OMPD_distribute_parallel_for:
15463 case OMPD_distribute_parallel_for_simd:
15464 case OMPD_parallel_master_taskloop:
15465 case OMPD_parallel_masked_taskloop:
15466 case OMPD_parallel_master_taskloop_simd:
15467 case OMPD_parallel_masked_taskloop_simd:
15468 // Do not capture num_threads-clause expressions.
15469 break;
15470 case OMPD_target_data:
15471 case OMPD_target_enter_data:
15472 case OMPD_target_exit_data:
15473 case OMPD_target_update:
15474 case OMPD_target:
15475 case OMPD_target_simd:
15476 case OMPD_target_teams:
15477 case OMPD_target_teams_distribute:
15478 case OMPD_target_teams_distribute_simd:
15479 case OMPD_cancel:
15480 case OMPD_task:
15481 case OMPD_taskloop:
15482 case OMPD_taskloop_simd:
15483 case OMPD_master_taskloop:
15484 case OMPD_masked_taskloop:
15485 case OMPD_master_taskloop_simd:
15486 case OMPD_masked_taskloop_simd:
15487 case OMPD_threadprivate:
15488 case OMPD_allocate:
15489 case OMPD_taskyield:
15490 case OMPD_error:
15491 case OMPD_barrier:
15492 case OMPD_taskwait:
15493 case OMPD_cancellation_point:
15494 case OMPD_flush:
15495 case OMPD_depobj:
15496 case OMPD_scan:
15497 case OMPD_declare_reduction:
15498 case OMPD_declare_mapper:
15499 case OMPD_declare_simd:
15500 case OMPD_declare_variant:
15501 case OMPD_begin_declare_variant:
15502 case OMPD_end_declare_variant:
15503 case OMPD_declare_target:
15504 case OMPD_end_declare_target:
15505 case OMPD_loop:
15506 case OMPD_teams_loop:
15507 case OMPD_target_teams_loop:
15508 case OMPD_teams:
15509 case OMPD_simd:
15510 case OMPD_tile:
15511 case OMPD_unroll:
15512 case OMPD_for:
15513 case OMPD_for_simd:
15514 case OMPD_sections:
15515 case OMPD_section:
15516 case OMPD_single:
15517 case OMPD_master:
15518 case OMPD_masked:
15519 case OMPD_critical:
15520 case OMPD_taskgroup:
15521 case OMPD_distribute:
15522 case OMPD_ordered:
15523 case OMPD_atomic:
15524 case OMPD_distribute_simd:
15525 case OMPD_teams_distribute:
15526 case OMPD_teams_distribute_simd:
15527 case OMPD_requires:
15528 case OMPD_metadirective:
15529 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", 15529)
;
15530 case OMPD_unknown:
15531 default:
15532 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15532)
;
15533 }
15534 break;
15535 case OMPC_num_teams:
15536 switch (DKind) {
15537 case OMPD_target_teams:
15538 case OMPD_target_teams_distribute:
15539 case OMPD_target_teams_distribute_simd:
15540 case OMPD_target_teams_distribute_parallel_for:
15541 case OMPD_target_teams_distribute_parallel_for_simd:
15542 case OMPD_target_teams_loop:
15543 CaptureRegion = OMPD_target;
15544 break;
15545 case OMPD_teams_distribute_parallel_for:
15546 case OMPD_teams_distribute_parallel_for_simd:
15547 case OMPD_teams:
15548 case OMPD_teams_distribute:
15549 case OMPD_teams_distribute_simd:
15550 case OMPD_teams_loop:
15551 // Do not capture num_teams-clause expressions.
15552 break;
15553 case OMPD_distribute_parallel_for:
15554 case OMPD_distribute_parallel_for_simd:
15555 case OMPD_task:
15556 case OMPD_taskloop:
15557 case OMPD_taskloop_simd:
15558 case OMPD_master_taskloop:
15559 case OMPD_masked_taskloop:
15560 case OMPD_master_taskloop_simd:
15561 case OMPD_masked_taskloop_simd:
15562 case OMPD_parallel_master_taskloop:
15563 case OMPD_parallel_masked_taskloop:
15564 case OMPD_parallel_master_taskloop_simd:
15565 case OMPD_parallel_masked_taskloop_simd:
15566 case OMPD_target_data:
15567 case OMPD_target_enter_data:
15568 case OMPD_target_exit_data:
15569 case OMPD_target_update:
15570 case OMPD_cancel:
15571 case OMPD_parallel:
15572 case OMPD_parallel_master:
15573 case OMPD_parallel_masked:
15574 case OMPD_parallel_sections:
15575 case OMPD_parallel_for:
15576 case OMPD_parallel_for_simd:
15577 case OMPD_parallel_loop:
15578 case OMPD_target:
15579 case OMPD_target_simd:
15580 case OMPD_target_parallel:
15581 case OMPD_target_parallel_for:
15582 case OMPD_target_parallel_for_simd:
15583 case OMPD_target_parallel_loop:
15584 case OMPD_threadprivate:
15585 case OMPD_allocate:
15586 case OMPD_taskyield:
15587 case OMPD_error:
15588 case OMPD_barrier:
15589 case OMPD_taskwait:
15590 case OMPD_cancellation_point:
15591 case OMPD_flush:
15592 case OMPD_depobj:
15593 case OMPD_scan:
15594 case OMPD_declare_reduction:
15595 case OMPD_declare_mapper:
15596 case OMPD_declare_simd:
15597 case OMPD_declare_variant:
15598 case OMPD_begin_declare_variant:
15599 case OMPD_end_declare_variant:
15600 case OMPD_declare_target:
15601 case OMPD_end_declare_target:
15602 case OMPD_loop:
15603 case OMPD_simd:
15604 case OMPD_tile:
15605 case OMPD_unroll:
15606 case OMPD_for:
15607 case OMPD_for_simd:
15608 case OMPD_sections:
15609 case OMPD_section:
15610 case OMPD_single:
15611 case OMPD_master:
15612 case OMPD_masked:
15613 case OMPD_critical:
15614 case OMPD_taskgroup:
15615 case OMPD_distribute:
15616 case OMPD_ordered:
15617 case OMPD_atomic:
15618 case OMPD_distribute_simd:
15619 case OMPD_requires:
15620 case OMPD_metadirective:
15621 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", 15621)
;
15622 case OMPD_unknown:
15623 default:
15624 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15624)
;
15625 }
15626 break;
15627 case OMPC_thread_limit:
15628 switch (DKind) {
15629 case OMPD_target_teams:
15630 case OMPD_target_teams_distribute:
15631 case OMPD_target_teams_distribute_simd:
15632 case OMPD_target_teams_distribute_parallel_for:
15633 case OMPD_target_teams_distribute_parallel_for_simd:
15634 case OMPD_target_teams_loop:
15635 CaptureRegion = OMPD_target;
15636 break;
15637 case OMPD_teams_distribute_parallel_for:
15638 case OMPD_teams_distribute_parallel_for_simd:
15639 case OMPD_teams:
15640 case OMPD_teams_distribute:
15641 case OMPD_teams_distribute_simd:
15642 case OMPD_teams_loop:
15643 // Do not capture thread_limit-clause expressions.
15644 break;
15645 case OMPD_distribute_parallel_for:
15646 case OMPD_distribute_parallel_for_simd:
15647 case OMPD_task:
15648 case OMPD_taskloop:
15649 case OMPD_taskloop_simd:
15650 case OMPD_master_taskloop:
15651 case OMPD_masked_taskloop:
15652 case OMPD_master_taskloop_simd:
15653 case OMPD_masked_taskloop_simd:
15654 case OMPD_parallel_master_taskloop:
15655 case OMPD_parallel_masked_taskloop:
15656 case OMPD_parallel_master_taskloop_simd:
15657 case OMPD_parallel_masked_taskloop_simd:
15658 case OMPD_target_data:
15659 case OMPD_target_enter_data:
15660 case OMPD_target_exit_data:
15661 case OMPD_target_update:
15662 case OMPD_cancel:
15663 case OMPD_parallel:
15664 case OMPD_parallel_master:
15665 case OMPD_parallel_masked:
15666 case OMPD_parallel_sections:
15667 case OMPD_parallel_for:
15668 case OMPD_parallel_for_simd:
15669 case OMPD_parallel_loop:
15670 case OMPD_target:
15671 case OMPD_target_simd:
15672 case OMPD_target_parallel:
15673 case OMPD_target_parallel_for:
15674 case OMPD_target_parallel_for_simd:
15675 case OMPD_target_parallel_loop:
15676 case OMPD_threadprivate:
15677 case OMPD_allocate:
15678 case OMPD_taskyield:
15679 case OMPD_error:
15680 case OMPD_barrier:
15681 case OMPD_taskwait:
15682 case OMPD_cancellation_point:
15683 case OMPD_flush:
15684 case OMPD_depobj:
15685 case OMPD_scan:
15686 case OMPD_declare_reduction:
15687 case OMPD_declare_mapper:
15688 case OMPD_declare_simd:
15689 case OMPD_declare_variant:
15690 case OMPD_begin_declare_variant:
15691 case OMPD_end_declare_variant:
15692 case OMPD_declare_target:
15693 case OMPD_end_declare_target:
15694 case OMPD_loop:
15695 case OMPD_simd:
15696 case OMPD_tile:
15697 case OMPD_unroll:
15698 case OMPD_for:
15699 case OMPD_for_simd:
15700 case OMPD_sections:
15701 case OMPD_section:
15702 case OMPD_single:
15703 case OMPD_master:
15704 case OMPD_masked:
15705 case OMPD_critical:
15706 case OMPD_taskgroup:
15707 case OMPD_distribute:
15708 case OMPD_ordered:
15709 case OMPD_atomic:
15710 case OMPD_distribute_simd:
15711 case OMPD_requires:
15712 case OMPD_metadirective:
15713 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", 15713)
;
15714 case OMPD_unknown:
15715 default:
15716 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15716)
;
15717 }
15718 break;
15719 case OMPC_schedule:
15720 switch (DKind) {
15721 case OMPD_parallel_for:
15722 case OMPD_parallel_for_simd:
15723 case OMPD_distribute_parallel_for:
15724 case OMPD_distribute_parallel_for_simd:
15725 case OMPD_teams_distribute_parallel_for:
15726 case OMPD_teams_distribute_parallel_for_simd:
15727 case OMPD_target_parallel_for:
15728 case OMPD_target_parallel_for_simd:
15729 case OMPD_target_teams_distribute_parallel_for:
15730 case OMPD_target_teams_distribute_parallel_for_simd:
15731 CaptureRegion = OMPD_parallel;
15732 break;
15733 case OMPD_for:
15734 case OMPD_for_simd:
15735 // Do not capture schedule-clause expressions.
15736 break;
15737 case OMPD_task:
15738 case OMPD_taskloop:
15739 case OMPD_taskloop_simd:
15740 case OMPD_master_taskloop:
15741 case OMPD_masked_taskloop:
15742 case OMPD_master_taskloop_simd:
15743 case OMPD_masked_taskloop_simd:
15744 case OMPD_parallel_master_taskloop:
15745 case OMPD_parallel_masked_taskloop:
15746 case OMPD_parallel_master_taskloop_simd:
15747 case OMPD_parallel_masked_taskloop_simd:
15748 case OMPD_target_data:
15749 case OMPD_target_enter_data:
15750 case OMPD_target_exit_data:
15751 case OMPD_target_update:
15752 case OMPD_teams:
15753 case OMPD_teams_distribute:
15754 case OMPD_teams_distribute_simd:
15755 case OMPD_target_teams_distribute:
15756 case OMPD_target_teams_distribute_simd:
15757 case OMPD_target:
15758 case OMPD_target_simd:
15759 case OMPD_target_parallel:
15760 case OMPD_cancel:
15761 case OMPD_parallel:
15762 case OMPD_parallel_master:
15763 case OMPD_parallel_masked:
15764 case OMPD_parallel_sections:
15765 case OMPD_threadprivate:
15766 case OMPD_allocate:
15767 case OMPD_taskyield:
15768 case OMPD_error:
15769 case OMPD_barrier:
15770 case OMPD_taskwait:
15771 case OMPD_cancellation_point:
15772 case OMPD_flush:
15773 case OMPD_depobj:
15774 case OMPD_scan:
15775 case OMPD_declare_reduction:
15776 case OMPD_declare_mapper:
15777 case OMPD_declare_simd:
15778 case OMPD_declare_variant:
15779 case OMPD_begin_declare_variant:
15780 case OMPD_end_declare_variant:
15781 case OMPD_declare_target:
15782 case OMPD_end_declare_target:
15783 case OMPD_loop:
15784 case OMPD_teams_loop:
15785 case OMPD_target_teams_loop:
15786 case OMPD_parallel_loop:
15787 case OMPD_target_parallel_loop:
15788 case OMPD_simd:
15789 case OMPD_tile:
15790 case OMPD_unroll:
15791 case OMPD_sections:
15792 case OMPD_section:
15793 case OMPD_single:
15794 case OMPD_master:
15795 case OMPD_masked:
15796 case OMPD_critical:
15797 case OMPD_taskgroup:
15798 case OMPD_distribute:
15799 case OMPD_ordered:
15800 case OMPD_atomic:
15801 case OMPD_distribute_simd:
15802 case OMPD_target_teams:
15803 case OMPD_requires:
15804 case OMPD_metadirective:
15805 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15805)
;
15806 case OMPD_unknown:
15807 default:
15808 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15808)
;
15809 }
15810 break;
15811 case OMPC_dist_schedule:
15812 switch (DKind) {
15813 case OMPD_teams_distribute_parallel_for:
15814 case OMPD_teams_distribute_parallel_for_simd:
15815 case OMPD_teams_distribute:
15816 case OMPD_teams_distribute_simd:
15817 case OMPD_target_teams_distribute_parallel_for:
15818 case OMPD_target_teams_distribute_parallel_for_simd:
15819 case OMPD_target_teams_distribute:
15820 case OMPD_target_teams_distribute_simd:
15821 CaptureRegion = OMPD_teams;
15822 break;
15823 case OMPD_distribute_parallel_for:
15824 case OMPD_distribute_parallel_for_simd:
15825 case OMPD_distribute:
15826 case OMPD_distribute_simd:
15827 // Do not capture dist_schedule-clause expressions.
15828 break;
15829 case OMPD_parallel_for:
15830 case OMPD_parallel_for_simd:
15831 case OMPD_target_parallel_for_simd:
15832 case OMPD_target_parallel_for:
15833 case OMPD_task:
15834 case OMPD_taskloop:
15835 case OMPD_taskloop_simd:
15836 case OMPD_master_taskloop:
15837 case OMPD_masked_taskloop:
15838 case OMPD_master_taskloop_simd:
15839 case OMPD_masked_taskloop_simd:
15840 case OMPD_parallel_master_taskloop:
15841 case OMPD_parallel_masked_taskloop:
15842 case OMPD_parallel_master_taskloop_simd:
15843 case OMPD_parallel_masked_taskloop_simd:
15844 case OMPD_target_data:
15845 case OMPD_target_enter_data:
15846 case OMPD_target_exit_data:
15847 case OMPD_target_update:
15848 case OMPD_teams:
15849 case OMPD_target:
15850 case OMPD_target_simd:
15851 case OMPD_target_parallel:
15852 case OMPD_cancel:
15853 case OMPD_parallel:
15854 case OMPD_parallel_master:
15855 case OMPD_parallel_masked:
15856 case OMPD_parallel_sections:
15857 case OMPD_threadprivate:
15858 case OMPD_allocate:
15859 case OMPD_taskyield:
15860 case OMPD_error:
15861 case OMPD_barrier:
15862 case OMPD_taskwait:
15863 case OMPD_cancellation_point:
15864 case OMPD_flush:
15865 case OMPD_depobj:
15866 case OMPD_scan:
15867 case OMPD_declare_reduction:
15868 case OMPD_declare_mapper:
15869 case OMPD_declare_simd:
15870 case OMPD_declare_variant:
15871 case OMPD_begin_declare_variant:
15872 case OMPD_end_declare_variant:
15873 case OMPD_declare_target:
15874 case OMPD_end_declare_target:
15875 case OMPD_loop:
15876 case OMPD_teams_loop:
15877 case OMPD_target_teams_loop:
15878 case OMPD_parallel_loop:
15879 case OMPD_target_parallel_loop:
15880 case OMPD_simd:
15881 case OMPD_tile:
15882 case OMPD_unroll:
15883 case OMPD_for:
15884 case OMPD_for_simd:
15885 case OMPD_sections:
15886 case OMPD_section:
15887 case OMPD_single:
15888 case OMPD_master:
15889 case OMPD_masked:
15890 case OMPD_critical:
15891 case OMPD_taskgroup:
15892 case OMPD_ordered:
15893 case OMPD_atomic:
15894 case OMPD_target_teams:
15895 case OMPD_requires:
15896 case OMPD_metadirective:
15897 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", 15897)
;
15898 case OMPD_unknown:
15899 default:
15900 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15900)
;
15901 }
15902 break;
15903 case OMPC_device:
15904 switch (DKind) {
15905 case OMPD_target_update:
15906 case OMPD_target_enter_data:
15907 case OMPD_target_exit_data:
15908 case OMPD_target:
15909 case OMPD_target_simd:
15910 case OMPD_target_teams:
15911 case OMPD_target_parallel:
15912 case OMPD_target_teams_distribute:
15913 case OMPD_target_teams_distribute_simd:
15914 case OMPD_target_parallel_for:
15915 case OMPD_target_parallel_for_simd:
15916 case OMPD_target_parallel_loop:
15917 case OMPD_target_teams_distribute_parallel_for:
15918 case OMPD_target_teams_distribute_parallel_for_simd:
15919 case OMPD_target_teams_loop:
15920 case OMPD_dispatch:
15921 CaptureRegion = OMPD_task;
15922 break;
15923 case OMPD_target_data:
15924 case OMPD_interop:
15925 // Do not capture device-clause expressions.
15926 break;
15927 case OMPD_teams_distribute_parallel_for:
15928 case OMPD_teams_distribute_parallel_for_simd:
15929 case OMPD_teams:
15930 case OMPD_teams_distribute:
15931 case OMPD_teams_distribute_simd:
15932 case OMPD_distribute_parallel_for:
15933 case OMPD_distribute_parallel_for_simd:
15934 case OMPD_task:
15935 case OMPD_taskloop:
15936 case OMPD_taskloop_simd:
15937 case OMPD_master_taskloop:
15938 case OMPD_masked_taskloop:
15939 case OMPD_master_taskloop_simd:
15940 case OMPD_masked_taskloop_simd:
15941 case OMPD_parallel_master_taskloop:
15942 case OMPD_parallel_masked_taskloop:
15943 case OMPD_parallel_master_taskloop_simd:
15944 case OMPD_parallel_masked_taskloop_simd:
15945 case OMPD_cancel:
15946 case OMPD_parallel:
15947 case OMPD_parallel_master:
15948 case OMPD_parallel_masked:
15949 case OMPD_parallel_sections:
15950 case OMPD_parallel_for:
15951 case OMPD_parallel_for_simd:
15952 case OMPD_threadprivate:
15953 case OMPD_allocate:
15954 case OMPD_taskyield:
15955 case OMPD_error:
15956 case OMPD_barrier:
15957 case OMPD_taskwait:
15958 case OMPD_cancellation_point:
15959 case OMPD_flush:
15960 case OMPD_depobj:
15961 case OMPD_scan:
15962 case OMPD_declare_reduction:
15963 case OMPD_declare_mapper:
15964 case OMPD_declare_simd:
15965 case OMPD_declare_variant:
15966 case OMPD_begin_declare_variant:
15967 case OMPD_end_declare_variant:
15968 case OMPD_declare_target:
15969 case OMPD_end_declare_target:
15970 case OMPD_loop:
15971 case OMPD_teams_loop:
15972 case OMPD_parallel_loop:
15973 case OMPD_simd:
15974 case OMPD_tile:
15975 case OMPD_unroll:
15976 case OMPD_for:
15977 case OMPD_for_simd:
15978 case OMPD_sections:
15979 case OMPD_section:
15980 case OMPD_single:
15981 case OMPD_master:
15982 case OMPD_masked:
15983 case OMPD_critical:
15984 case OMPD_taskgroup:
15985 case OMPD_distribute:
15986 case OMPD_ordered:
15987 case OMPD_atomic:
15988 case OMPD_distribute_simd:
15989 case OMPD_requires:
15990 case OMPD_metadirective:
15991 llvm_unreachable("Unexpected OpenMP directive with device-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with device-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 15991)
;
15992 case OMPD_unknown:
15993 default:
15994 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 15994)
;
15995 }
15996 break;
15997 case OMPC_grainsize:
15998 case OMPC_num_tasks:
15999 case OMPC_final:
16000 case OMPC_priority:
16001 switch (DKind) {
16002 case OMPD_task:
16003 case OMPD_taskloop:
16004 case OMPD_taskloop_simd:
16005 case OMPD_master_taskloop:
16006 case OMPD_masked_taskloop:
16007 case OMPD_master_taskloop_simd:
16008 case OMPD_masked_taskloop_simd:
16009 break;
16010 case OMPD_parallel_masked_taskloop:
16011 case OMPD_parallel_masked_taskloop_simd:
16012 case OMPD_parallel_master_taskloop:
16013 case OMPD_parallel_master_taskloop_simd:
16014 CaptureRegion = OMPD_parallel;
16015 break;
16016 case OMPD_target_update:
16017 case OMPD_target_enter_data:
16018 case OMPD_target_exit_data:
16019 case OMPD_target:
16020 case OMPD_target_simd:
16021 case OMPD_target_teams:
16022 case OMPD_target_parallel:
16023 case OMPD_target_teams_distribute:
16024 case OMPD_target_teams_distribute_simd:
16025 case OMPD_target_parallel_for:
16026 case OMPD_target_parallel_for_simd:
16027 case OMPD_target_teams_distribute_parallel_for:
16028 case OMPD_target_teams_distribute_parallel_for_simd:
16029 case OMPD_target_data:
16030 case OMPD_teams_distribute_parallel_for:
16031 case OMPD_teams_distribute_parallel_for_simd:
16032 case OMPD_teams:
16033 case OMPD_teams_distribute:
16034 case OMPD_teams_distribute_simd:
16035 case OMPD_distribute_parallel_for:
16036 case OMPD_distribute_parallel_for_simd:
16037 case OMPD_cancel:
16038 case OMPD_parallel:
16039 case OMPD_parallel_master:
16040 case OMPD_parallel_masked:
16041 case OMPD_parallel_sections:
16042 case OMPD_parallel_for:
16043 case OMPD_parallel_for_simd:
16044 case OMPD_threadprivate:
16045 case OMPD_allocate:
16046 case OMPD_taskyield:
16047 case OMPD_error:
16048 case OMPD_barrier:
16049 case OMPD_taskwait:
16050 case OMPD_cancellation_point:
16051 case OMPD_flush:
16052 case OMPD_depobj:
16053 case OMPD_scan:
16054 case OMPD_declare_reduction:
16055 case OMPD_declare_mapper:
16056 case OMPD_declare_simd:
16057 case OMPD_declare_variant:
16058 case OMPD_begin_declare_variant:
16059 case OMPD_end_declare_variant:
16060 case OMPD_declare_target:
16061 case OMPD_end_declare_target:
16062 case OMPD_loop:
16063 case OMPD_teams_loop:
16064 case OMPD_target_teams_loop:
16065 case OMPD_parallel_loop:
16066 case OMPD_target_parallel_loop:
16067 case OMPD_simd:
16068 case OMPD_tile:
16069 case OMPD_unroll:
16070 case OMPD_for:
16071 case OMPD_for_simd:
16072 case OMPD_sections:
16073 case OMPD_section:
16074 case OMPD_single:
16075 case OMPD_master:
16076 case OMPD_masked:
16077 case OMPD_critical:
16078 case OMPD_taskgroup:
16079 case OMPD_distribute:
16080 case OMPD_ordered:
16081 case OMPD_atomic:
16082 case OMPD_distribute_simd:
16083 case OMPD_requires:
16084 case OMPD_metadirective:
16085 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 16085)
;
16086 case OMPD_unknown:
16087 default:
16088 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 16088)
;
16089 }
16090 break;
16091 case OMPC_novariants:
16092 case OMPC_nocontext:
16093 switch (DKind) {
16094 case OMPD_dispatch:
16095 CaptureRegion = OMPD_task;
16096 break;
16097 default:
16098 llvm_unreachable("Unexpected OpenMP directive")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive"
, "clang/lib/Sema/SemaOpenMP.cpp", 16098)
;
16099 }
16100 break;
16101 case OMPC_filter:
16102 // Do not capture filter-clause expressions.
16103 break;
16104 case OMPC_when:
16105 if (DKind == OMPD_metadirective) {
16106 CaptureRegion = OMPD_metadirective;
16107 } else if (DKind == OMPD_unknown) {
16108 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"clang/lib/Sema/SemaOpenMP.cpp", 16108)
;
16109 } else {
16110 llvm_unreachable("Unexpected OpenMP directive with when clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with when clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 16110)
;
16111 }
16112 break;
16113 case OMPC_firstprivate:
16114 case OMPC_lastprivate:
16115 case OMPC_reduction:
16116 case OMPC_task_reduction:
16117 case OMPC_in_reduction:
16118 case OMPC_linear:
16119 case OMPC_default:
16120 case OMPC_proc_bind:
16121 case OMPC_safelen:
16122 case OMPC_simdlen:
16123 case OMPC_sizes:
16124 case OMPC_allocator:
16125 case OMPC_collapse:
16126 case OMPC_private:
16127 case OMPC_shared:
16128 case OMPC_aligned:
16129 case OMPC_copyin:
16130 case OMPC_copyprivate:
16131 case OMPC_ordered:
16132 case OMPC_nowait:
16133 case OMPC_untied:
16134 case OMPC_mergeable:
16135 case OMPC_threadprivate:
16136 case OMPC_allocate:
16137 case OMPC_flush:
16138 case OMPC_depobj:
16139 case OMPC_read:
16140 case OMPC_write:
16141 case OMPC_update:
16142 case OMPC_capture:
16143 case OMPC_compare:
16144 case OMPC_seq_cst:
16145 case OMPC_acq_rel:
16146 case OMPC_acquire:
16147 case OMPC_release:
16148 case OMPC_relaxed:
16149 case OMPC_depend:
16150 case OMPC_threads:
16151 case OMPC_simd:
16152 case OMPC_map:
16153 case OMPC_nogroup:
16154 case OMPC_hint:
16155 case OMPC_defaultmap:
16156 case OMPC_unknown:
16157 case OMPC_uniform:
16158 case OMPC_to:
16159 case OMPC_from:
16160 case OMPC_use_device_ptr:
16161 case OMPC_use_device_addr:
16162 case OMPC_is_device_ptr:
16163 case OMPC_unified_address:
16164 case OMPC_unified_shared_memory:
16165 case OMPC_reverse_offload:
16166 case OMPC_dynamic_allocators:
16167 case OMPC_atomic_default_mem_order:
16168 case OMPC_device_type:
16169 case OMPC_match:
16170 case OMPC_nontemporal:
16171 case OMPC_order:
16172 case OMPC_at:
16173 case OMPC_severity:
16174 case OMPC_message:
16175 case OMPC_destroy:
16176 case OMPC_detach:
16177 case OMPC_inclusive:
16178 case OMPC_exclusive:
16179 case OMPC_uses_allocators:
16180 case OMPC_affinity:
16181 case OMPC_bind:
16182 default:
16183 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "clang/lib/Sema/SemaOpenMP.cpp", 16183)
;
16184 }
16185 return CaptureRegion;
16186}
16187
16188OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16189 Expr *Condition, SourceLocation StartLoc,
16190 SourceLocation LParenLoc,
16191 SourceLocation NameModifierLoc,
16192 SourceLocation ColonLoc,
16193 SourceLocation EndLoc) {
16194 Expr *ValExpr = Condition;
16195 Stmt *HelperValStmt = nullptr;
16196 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16197 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16198 !Condition->isInstantiationDependent() &&
16199 !Condition->containsUnexpandedParameterPack()) {
16200 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16201 if (Val.isInvalid())
16202 return nullptr;
16203
16204 ValExpr = Val.get();
16205
16206 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16207 CaptureRegion = getOpenMPCaptureRegionForClause(
16208 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16209 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16210 ValExpr = MakeFullExpr(ValExpr).get();
16211 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16212 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16213 HelperValStmt = buildPreInits(Context, Captures);
16214 }
16215 }
16216
16217 return new (Context)
16218 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16219 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16220}
16221
16222OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16223 SourceLocation StartLoc,
16224 SourceLocation LParenLoc,
16225 SourceLocation EndLoc) {
16226 Expr *ValExpr = Condition;
16227 Stmt *HelperValStmt = nullptr;
16228 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16229 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16230 !Condition->isInstantiationDependent() &&
16231 !Condition->containsUnexpandedParameterPack()) {
16232 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16233 if (Val.isInvalid())
16234 return nullptr;
16235
16236 ValExpr = MakeFullExpr(Val.get()).get();
16237
16238 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16239 CaptureRegion =
16240 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16241 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16242 ValExpr = MakeFullExpr(ValExpr).get();
16243 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16244 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16245 HelperValStmt = buildPreInits(Context, Captures);
16246 }
16247 }
16248
16249 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16250 StartLoc, LParenLoc, EndLoc);
16251}
16252
16253ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16254 Expr *Op) {
16255 if (!Op)
16256 return ExprError();
16257
16258 class IntConvertDiagnoser : public ICEConvertDiagnoser {
16259 public:
16260 IntConvertDiagnoser()
16261 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16262 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16263 QualType T) override {
16264 return S.Diag(Loc, diag::err_omp_not_integral) << T;
16265 }
16266 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16267 QualType T) override {
16268 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16269 }
16270 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16271 QualType T,
16272 QualType ConvTy) override {
16273 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16274 }
16275 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16276 QualType ConvTy) override {
16277 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16278 << ConvTy->isEnumeralType() << ConvTy;
16279 }
16280 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16281 QualType T) override {
16282 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16283 }
16284 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16285 QualType ConvTy) override {
16286 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16287 << ConvTy->isEnumeralType() << ConvTy;
16288 }
16289 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16290 QualType) override {
16291 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "clang/lib/Sema/SemaOpenMP.cpp", 16291)
;
16292 }
16293 } ConvertDiagnoser;
16294 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16295}
16296
16297static bool
16298isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16299 bool StrictlyPositive, bool BuildCapture = false,
16300 OpenMPDirectiveKind DKind = OMPD_unknown,
16301 OpenMPDirectiveKind *CaptureRegion = nullptr,
16302 Stmt **HelperValStmt = nullptr) {
16303 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16304 !ValExpr->isInstantiationDependent()) {
16305 SourceLocation Loc = ValExpr->getExprLoc();
16306 ExprResult Value =
16307 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16308 if (Value.isInvalid())
16309 return false;
16310
16311 ValExpr = Value.get();
16312 // The expression must evaluate to a non-negative integer value.
16313 if (Optional<llvm::APSInt> Result =
16314 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16315 if (Result->isSigned() &&
16316 !((!StrictlyPositive && Result->isNonNegative()) ||
16317 (StrictlyPositive && Result->isStrictlyPositive()))) {
16318 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16319 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16320 << ValExpr->getSourceRange();
16321 return false;
16322 }
16323 }
16324 if (!BuildCapture)
16325 return true;
16326 *CaptureRegion =
16327 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16328 if (*CaptureRegion != OMPD_unknown &&
16329 !SemaRef.CurContext->isDependentContext()) {
16330 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16331 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16332 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16333 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16334 }
16335 }
16336 return true;
16337}
16338
16339OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16340 SourceLocation StartLoc,
16341 SourceLocation LParenLoc,
16342 SourceLocation EndLoc) {
16343 Expr *ValExpr = NumThreads;
16344 Stmt *HelperValStmt = nullptr;
16345
16346 // OpenMP [2.5, Restrictions]
16347 // The num_threads expression must evaluate to a positive integer value.
16348 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16349 /*StrictlyPositive=*/true))
16350 return nullptr;
16351
16352 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16353 OpenMPDirectiveKind CaptureRegion =
16354 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16355 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16356 ValExpr = MakeFullExpr(ValExpr).get();
16357 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16358 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16359 HelperValStmt = buildPreInits(Context, Captures);
16360 }
16361
16362 return new (Context) OMPNumThreadsClause(
16363 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16364}
16365
16366ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16367 OpenMPClauseKind CKind,
16368 bool StrictlyPositive,
16369 bool SuppressExprDiags) {
16370 if (!E)
16371 return ExprError();
16372 if (E->isValueDependent() || E->isTypeDependent() ||
16373 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16374 return E;
16375
16376 llvm::APSInt Result;
16377 ExprResult ICE;
16378 if (SuppressExprDiags) {
16379 // Use a custom diagnoser that suppresses 'note' diagnostics about the
16380 // expression.
16381 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16382 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16383 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16384 SourceLocation Loc) override {
16385 llvm_unreachable("Diagnostic suppressed")::llvm::llvm_unreachable_internal("Diagnostic suppressed", "clang/lib/Sema/SemaOpenMP.cpp"
, 16385)
;
16386 }
16387 } Diagnoser;
16388 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16389 } else {
16390 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16391 }
16392 if (ICE.isInvalid())
16393 return ExprError();
16394
16395 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16396 (!StrictlyPositive && !Result.isNonNegative())) {
16397 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16398 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16399 << E->getSourceRange();
16400 return ExprError();
16401 }
16402 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16403 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16404 << E->getSourceRange();
16405 return ExprError();
16406 }
16407 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
16408 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
16409 else if (CKind == OMPC_ordered)
16410 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
16411 return ICE;
16412}
16413
16414OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16415 SourceLocation LParenLoc,
16416 SourceLocation EndLoc) {
16417 // OpenMP [2.8.1, simd construct, Description]
16418 // The parameter of the safelen clause must be a constant
16419 // positive integer expression.
16420 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16421 if (Safelen.isInvalid())
16422 return nullptr;
16423 return new (Context)
16424 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16425}
16426
16427OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16428 SourceLocation LParenLoc,
16429 SourceLocation EndLoc) {
16430 // OpenMP [2.8.1, simd construct, Description]
16431 // The parameter of the simdlen clause must be a constant
16432 // positive integer expression.
16433 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16434 if (Simdlen.isInvalid())
16435 return nullptr;
16436 return new (Context)
16437 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16438}
16439
16440/// Tries to find omp_allocator_handle_t type.
16441static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16442 DSAStackTy *Stack) {
16443 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
16444 if (!OMPAllocatorHandleT.isNull())
16445 return true;
16446 // Build the predefined allocator expressions.
16447 bool ErrorFound = false;
16448 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16449 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16450 StringRef Allocator =
16451 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16452 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16453 auto *VD = dyn_cast_or_null<ValueDecl>(
16454 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16455 if (!VD) {
16456 ErrorFound = true;
16457 break;
16458 }
16459 QualType AllocatorType =
16460 VD->getType().getNonLValueExprType(S.getASTContext());
16461 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16462 if (!Res.isUsable()) {
16463 ErrorFound = true;
16464 break;
16465 }
16466 if (OMPAllocatorHandleT.isNull())
16467 OMPAllocatorHandleT = AllocatorType;
16468 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
16469 ErrorFound = true;
16470 break;
16471 }
16472 Stack->setAllocator(AllocatorKind, Res.get());
16473 }
16474 if (ErrorFound) {
16475 S.Diag(Loc, diag::err_omp_implied_type_not_found)
16476 << "omp_allocator_handle_t";
16477 return false;
16478 }
16479 OMPAllocatorHandleT.addConst();
16480 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
16481 return true;
16482}
16483
16484OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16485 SourceLocation LParenLoc,
16486 SourceLocation EndLoc) {
16487 // OpenMP [2.11.3, allocate Directive, Description]
16488 // allocator is an expression of omp_allocator_handle_t type.
16489 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
16490 return nullptr;
16491
16492 ExprResult Allocator = DefaultLvalueConversion(A);
16493 if (Allocator.isInvalid())
16494 return nullptr;
16495 Allocator = PerformImplicitConversion(Allocator.get(),
16496 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
16497 Sema::AA_Initializing,
16498 /*AllowExplicit=*/true);
16499 if (Allocator.isInvalid())
16500 return nullptr;
16501 return new (Context)
16502 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16503}
16504
16505OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16506 SourceLocation StartLoc,
16507 SourceLocation LParenLoc,
16508 SourceLocation EndLoc) {
16509 // OpenMP [2.7.1, loop construct, Description]
16510 // OpenMP [2.8.1, simd construct, Description]
16511 // OpenMP [2.9.6, distribute construct, Description]
16512 // The parameter of the collapse clause must be a constant
16513 // positive integer expression.
16514 ExprResult NumForLoopsResult =
16515 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16516 if (NumForLoopsResult.isInvalid())
16517 return nullptr;
16518 return new (Context)
16519 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16520}
16521
16522OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16523 SourceLocation EndLoc,
16524 SourceLocation LParenLoc,
16525 Expr *NumForLoops) {
16526 // OpenMP [2.7.1, loop construct, Description]
16527 // OpenMP [2.8.1, simd construct, Description]
16528 // OpenMP [2.9.6, distribute construct, Description]
16529 // The parameter of the ordered clause must be a constant
16530 // positive integer expression if any.
16531 if (NumForLoops && LParenLoc.isValid()) {
16532 ExprResult NumForLoopsResult =
16533 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16534 if (NumForLoopsResult.isInvalid())
16535 return nullptr;
16536 NumForLoops = NumForLoopsResult.get();
16537 } else {
16538 NumForLoops = nullptr;
16539 }
16540 auto *Clause = OMPOrderedClause::Create(
16541 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
16542 StartLoc, LParenLoc, EndLoc);
16543 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16544 return Clause;
16545}
16546
16547OMPClause *Sema::ActOnOpenMPSimpleClause(
16548 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16549 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16550 OMPClause *Res = nullptr;
16551 switch (Kind) {
16552 case OMPC_default:
16553 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16554 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16555 break;
16556 case OMPC_proc_bind:
16557 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16558 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16559 break;
16560 case OMPC_atomic_default_mem_order:
16561 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16562 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16563 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16564 break;
16565 case OMPC_update:
16566 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16567 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16568 break;
16569 case OMPC_bind:
16570 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16571 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16572 break;
16573 case OMPC_at:
16574 Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16575 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16576 break;
16577 case OMPC_severity:
16578 Res = ActOnOpenMPSeverityClause(
16579 static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16580 LParenLoc, EndLoc);
16581 break;
16582 case OMPC_if:
16583 case OMPC_final:
16584 case OMPC_num_threads:
16585 case OMPC_safelen:
16586 case OMPC_simdlen:
16587 case OMPC_sizes:
16588 case OMPC_allocator:
16589 case OMPC_collapse:
16590 case OMPC_schedule:
16591 case OMPC_private:
16592 case OMPC_firstprivate:
16593 case OMPC_lastprivate:
16594 case OMPC_shared:
16595 case OMPC_reduction:
16596 case OMPC_task_reduction:
16597 case OMPC_in_reduction:
16598 case OMPC_linear:
16599 case OMPC_aligned:
16600 case OMPC_copyin:
16601 case OMPC_copyprivate:
16602 case OMPC_ordered:
16603 case OMPC_nowait:
16604 case OMPC_untied:
16605 case OMPC_mergeable:
16606 case OMPC_threadprivate:
16607 case OMPC_allocate:
16608 case OMPC_flush:
16609 case OMPC_depobj:
16610 case OMPC_read:
16611 case OMPC_write:
16612 case OMPC_capture:
16613 case OMPC_compare:
16614 case OMPC_seq_cst:
16615 case OMPC_acq_rel:
16616 case OMPC_acquire:
16617 case OMPC_release:
16618 case OMPC_relaxed:
16619 case OMPC_depend:
16620 case OMPC_device:
16621 case OMPC_threads:
16622 case OMPC_simd:
16623 case OMPC_map:
16624 case OMPC_num_teams:
16625 case OMPC_thread_limit:
16626 case OMPC_priority:
16627 case OMPC_grainsize:
16628 case OMPC_nogroup:
16629 case OMPC_num_tasks:
16630 case OMPC_hint:
16631 case OMPC_dist_schedule:
16632 case OMPC_defaultmap:
16633 case OMPC_unknown:
16634 case OMPC_uniform:
16635 case OMPC_to:
16636 case OMPC_from:
16637 case OMPC_use_device_ptr:
16638 case OMPC_use_device_addr:
16639 case OMPC_is_device_ptr:
16640 case OMPC_has_device_addr:
16641 case OMPC_unified_address:
16642 case OMPC_unified_shared_memory:
16643 case OMPC_reverse_offload:
16644 case OMPC_dynamic_allocators:
16645 case OMPC_device_type:
16646 case OMPC_match:
16647 case OMPC_nontemporal:
16648 case OMPC_destroy:
16649 case OMPC_novariants:
16650 case OMPC_nocontext:
16651 case OMPC_detach:
16652 case OMPC_inclusive:
16653 case OMPC_exclusive:
16654 case OMPC_uses_allocators:
16655 case OMPC_affinity:
16656 case OMPC_when:
16657 case OMPC_message:
16658 default:
16659 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 16659)
;
16660 }
16661 return Res;
16662}
16663
16664static std::string
16665getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
16666 ArrayRef<unsigned> Exclude = std::nullopt) {
16667 SmallString<256> Buffer;
16668 llvm::raw_svector_ostream Out(Buffer);
16669 unsigned Skipped = Exclude.size();
16670 for (unsigned I = First; I < Last; ++I) {
16671 if (llvm::is_contained(Exclude, I)) {
16672 --Skipped;
16673 continue;
16674 }
16675 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
16676 if (I + Skipped + 2 == Last)
16677 Out << " or ";
16678 else if (I + Skipped + 1 != Last)
16679 Out << ", ";
16680 }
16681 return std::string(Out.str());
16682}
16683
16684OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
16685 SourceLocation KindKwLoc,
16686 SourceLocation StartLoc,
16687 SourceLocation LParenLoc,
16688 SourceLocation EndLoc) {
16689 if (Kind == OMP_DEFAULT_unknown) {
16690 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16691 << getListOfPossibleValues(OMPC_default, /*First=*/0,
16692 /*Last=*/unsigned(OMP_DEFAULT_unknown))
16693 << getOpenMPClauseName(OMPC_default);
16694 return nullptr;
16695 }
16696
16697 switch (Kind) {
16698 case OMP_DEFAULT_none:
16699 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
16700 break;
16701 case OMP_DEFAULT_shared:
16702 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
16703 break;
16704 case OMP_DEFAULT_firstprivate:
16705 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
16706 break;
16707 case OMP_DEFAULT_private:
16708 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAPrivate(KindKwLoc);
16709 break;
16710 default:
16711 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "clang/lib/Sema/SemaOpenMP.cpp", 16711)
;
16712 }
16713
16714 return new (Context)
16715 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16716}
16717
16718OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
16719 SourceLocation KindKwLoc,
16720 SourceLocation StartLoc,
16721 SourceLocation LParenLoc,
16722 SourceLocation EndLoc) {
16723 if (Kind == OMP_PROC_BIND_unknown) {
16724 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16725 << getListOfPossibleValues(OMPC_proc_bind,
16726 /*First=*/unsigned(OMP_PROC_BIND_master),
16727 /*Last=*/
16728 unsigned(LangOpts.OpenMP > 50
16729 ? OMP_PROC_BIND_primary
16730 : OMP_PROC_BIND_spread) +
16731 1)
16732 << getOpenMPClauseName(OMPC_proc_bind);
16733 return nullptr;
16734 }
16735 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16736 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16737 << getListOfPossibleValues(OMPC_proc_bind,
16738 /*First=*/unsigned(OMP_PROC_BIND_master),
16739 /*Last=*/
16740 unsigned(OMP_PROC_BIND_spread) + 1)
16741 << getOpenMPClauseName(OMPC_proc_bind);
16742 return new (Context)
16743 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16744}
16745
16746OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
16747 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
16748 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16749 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
16750 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16751 << getListOfPossibleValues(
16752 OMPC_atomic_default_mem_order, /*First=*/0,
16753 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
16754 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16755 return nullptr;
16756 }
16757 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16758 LParenLoc, EndLoc);
16759}
16760
16761OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
16762 SourceLocation KindKwLoc,
16763 SourceLocation StartLoc,
16764 SourceLocation LParenLoc,
16765 SourceLocation EndLoc) {
16766 if (Kind == OMPC_AT_unknown) {
16767 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16768 << getListOfPossibleValues(OMPC_at, /*First=*/0,
16769 /*Last=*/OMPC_AT_unknown)
16770 << getOpenMPClauseName(OMPC_at);
16771 return nullptr;
16772 }
16773 return new (Context)
16774 OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16775}
16776
16777OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
16778 SourceLocation KindKwLoc,
16779 SourceLocation StartLoc,
16780 SourceLocation LParenLoc,
16781 SourceLocation EndLoc) {
16782 if (Kind == OMPC_SEVERITY_unknown) {
16783 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16784 << getListOfPossibleValues(OMPC_severity, /*First=*/0,
16785 /*Last=*/OMPC_SEVERITY_unknown)
16786 << getOpenMPClauseName(OMPC_severity);
16787 return nullptr;
16788 }
16789 return new (Context)
16790 OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16791}
16792
16793OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
16794 SourceLocation LParenLoc,
16795 SourceLocation EndLoc) {
16796 assert(ME && "NULL expr in Message clause")(static_cast <bool> (ME && "NULL expr in Message clause"
) ? void (0) : __assert_fail ("ME && \"NULL expr in Message clause\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16796, __extension__ __PRETTY_FUNCTION__
))
;
16797 if (!isa<StringLiteral>(ME)) {
16798 Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
16799 << getOpenMPClauseName(OMPC_message);
16800 return nullptr;
16801 }
16802 return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
16803}
16804
16805OMPClause *Sema::ActOnOpenMPOrderClause(
16806 OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
16807 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16808 SourceLocation KindLoc, SourceLocation EndLoc) {
16809 if (Kind != OMPC_ORDER_concurrent ||
16810 (LangOpts.OpenMP < 51 && MLoc.isValid())) {
16811 // Kind should be concurrent,
16812 // Modifiers introduced in OpenMP 5.1
16813 static_assert(OMPC_ORDER_unknown > 0,
16814 "OMPC_ORDER_unknown not greater than 0");
16815
16816 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16817 << getListOfPossibleValues(OMPC_order,
16818 /*First=*/0,
16819 /*Last=*/OMPC_ORDER_unknown)
16820 << getOpenMPClauseName(OMPC_order);
16821 return nullptr;
16822 }
16823 if (LangOpts.OpenMP >= 51) {
16824 if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
16825 Diag(MLoc, diag::err_omp_unexpected_clause_value)
16826 << getListOfPossibleValues(OMPC_order,
16827 /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
16828 /*Last=*/OMPC_ORDER_MODIFIER_last)
16829 << getOpenMPClauseName(OMPC_order);
16830 } else {
16831 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
16832 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
16833 // mark the current scope with 'order' flag
16834 unsigned existingFlags = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()->getFlags();
16835 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()->setFlags(existingFlags |
16836 Scope::OpenMPOrderClauseScope);
16837 }
16838 }
16839 }
16840 return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
16841 EndLoc, Modifier, MLoc);
16842}
16843
16844OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
16845 SourceLocation KindKwLoc,
16846 SourceLocation StartLoc,
16847 SourceLocation LParenLoc,
16848 SourceLocation EndLoc) {
16849 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16850 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16851 SmallVector<unsigned> Except = {
16852 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16853 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16854 if (LangOpts.OpenMP < 51)
16855 Except.push_back(OMPC_DEPEND_inoutset);
16856 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16857 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16858 /*Last=*/OMPC_DEPEND_unknown, Except)
16859 << getOpenMPClauseName(OMPC_update);
16860 return nullptr;
16861 }
16862 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
16863 EndLoc);
16864}
16865
16866OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
16867 SourceLocation StartLoc,
16868 SourceLocation LParenLoc,
16869 SourceLocation EndLoc) {
16870 for (Expr *SizeExpr : SizeExprs) {
16871 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
16872 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
16873 if (!NumForLoopsResult.isUsable())
16874 return nullptr;
16875 }
16876
16877 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(SizeExprs.size());
16878 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16879 SizeExprs);
16880}
16881
16882OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
16883 SourceLocation EndLoc) {
16884 return OMPFullClause::Create(Context, StartLoc, EndLoc);
16885}
16886
16887OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
16888 SourceLocation StartLoc,
16889 SourceLocation LParenLoc,
16890 SourceLocation EndLoc) {
16891 if (FactorExpr) {
16892 // If an argument is specified, it must be a constant (or an unevaluated
16893 // template expression).
16894 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16895 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16896 if (FactorResult.isInvalid())
16897 return nullptr;
16898 FactorExpr = FactorResult.get();
16899 }
16900
16901 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16902 FactorExpr);
16903}
16904
16905OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
16906 SourceLocation LParenLoc,
16907 SourceLocation EndLoc) {
16908 ExprResult AlignVal;
16909 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16910 if (AlignVal.isInvalid())
16911 return nullptr;
16912 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
16913 EndLoc);
16914}
16915
16916OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
16917 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
16918 SourceLocation StartLoc, SourceLocation LParenLoc,
16919 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
16920 SourceLocation EndLoc) {
16921 OMPClause *Res = nullptr;
16922 switch (Kind) {
16923 case OMPC_schedule:
16924 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16925 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", 16926, __extension__ __PRETTY_FUNCTION__
))
16926 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", 16926, __extension__ __PRETTY_FUNCTION__
))
;
16927 Res = ActOnOpenMPScheduleClause(
16928 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
16929 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
16930 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
16931 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16932 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16933 break;
16934 case OMPC_if:
16935 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", 16935, __extension__ __PRETTY_FUNCTION__
))
;
16936 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
16937 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16938 DelimLoc, EndLoc);
16939 break;
16940 case OMPC_dist_schedule:
16941 Res = ActOnOpenMPDistScheduleClause(
16942 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
16943 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16944 break;
16945 case OMPC_defaultmap:
16946 enum { Modifier, DefaultmapKind };
16947 Res = ActOnOpenMPDefaultmapClause(
16948 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
16949 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
16950 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16951 EndLoc);
16952 break;
16953 case OMPC_order:
16954 enum { OrderModifier, OrderKind };
16955 Res = ActOnOpenMPOrderClause(
16956 static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
16957 static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
16958 LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
16959 break;
16960 case OMPC_device:
16961 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", 16961, __extension__ __PRETTY_FUNCTION__
))
;
16962 Res = ActOnOpenMPDeviceClause(
16963 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
16964 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16965 break;
16966 case OMPC_grainsize:
16967 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1 && "Modifier for grainsize clause and its location are expected."
) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1 && \"Modifier for grainsize clause and its location are expected.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16968, __extension__ __PRETTY_FUNCTION__
))
16968 "Modifier for grainsize clause and its location are expected.")(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1 && "Modifier for grainsize clause and its location are expected."
) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1 && \"Modifier for grainsize clause and its location are expected.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16968, __extension__ __PRETTY_FUNCTION__
))
;
16969 Res = ActOnOpenMPGrainsizeClause(
16970 static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
16971 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16972 break;
16973 case OMPC_num_tasks:
16974 assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1 && "Modifier for num_tasks clause and its location are expected."
) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1 && \"Modifier for num_tasks clause and its location are expected.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16975, __extension__ __PRETTY_FUNCTION__
))
16975 "Modifier for num_tasks clause and its location are expected.")(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1 && "Modifier for num_tasks clause and its location are expected."
) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1 && \"Modifier for num_tasks clause and its location are expected.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 16975, __extension__ __PRETTY_FUNCTION__
))
;
16976 Res = ActOnOpenMPNumTasksClause(
16977 static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
16978 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16979 break;
16980 case OMPC_final:
16981 case OMPC_num_threads:
16982 case OMPC_safelen:
16983 case OMPC_simdlen:
16984 case OMPC_sizes:
16985 case OMPC_allocator:
16986 case OMPC_collapse:
16987 case OMPC_default:
16988 case OMPC_proc_bind:
16989 case OMPC_private:
16990 case OMPC_firstprivate:
16991 case OMPC_lastprivate:
16992 case OMPC_shared:
16993 case OMPC_reduction:
16994 case OMPC_task_reduction:
16995 case OMPC_in_reduction:
16996 case OMPC_linear:
16997 case OMPC_aligned:
16998 case OMPC_copyin:
16999 case OMPC_copyprivate:
17000 case OMPC_ordered:
17001 case OMPC_nowait:
17002 case OMPC_untied:
17003 case OMPC_mergeable:
17004 case OMPC_threadprivate:
17005 case OMPC_allocate:
17006 case OMPC_flush:
17007 case OMPC_depobj:
17008 case OMPC_read:
17009 case OMPC_write:
17010 case OMPC_update:
17011 case OMPC_capture:
17012 case OMPC_compare:
17013 case OMPC_seq_cst:
17014 case OMPC_acq_rel:
17015 case OMPC_acquire:
17016 case OMPC_release:
17017 case OMPC_relaxed:
17018 case OMPC_depend:
17019 case OMPC_threads:
17020 case OMPC_simd:
17021 case OMPC_map:
17022 case OMPC_num_teams:
17023 case OMPC_thread_limit:
17024 case OMPC_priority:
17025 case OMPC_nogroup:
17026 case OMPC_hint:
17027 case OMPC_unknown:
17028 case OMPC_uniform:
17029 case OMPC_to:
17030 case OMPC_from:
17031 case OMPC_use_device_ptr:
17032 case OMPC_use_device_addr:
17033 case OMPC_is_device_ptr:
17034 case OMPC_has_device_addr:
17035 case OMPC_unified_address:
17036 case OMPC_unified_shared_memory:
17037 case OMPC_reverse_offload:
17038 case OMPC_dynamic_allocators:
17039 case OMPC_atomic_default_mem_order:
17040 case OMPC_device_type:
17041 case OMPC_match:
17042 case OMPC_nontemporal:
17043 case OMPC_at:
17044 case OMPC_severity:
17045 case OMPC_message:
17046 case OMPC_destroy:
17047 case OMPC_novariants:
17048 case OMPC_nocontext:
17049 case OMPC_detach:
17050 case OMPC_inclusive:
17051 case OMPC_exclusive:
17052 case OMPC_uses_allocators:
17053 case OMPC_affinity:
17054 case OMPC_when:
17055 case OMPC_bind:
17056 default:
17057 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 17057)
;
17058 }
17059 return Res;
17060}
17061
17062static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17063 OpenMPScheduleClauseModifier M2,
17064 SourceLocation M1Loc, SourceLocation M2Loc) {
17065 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17066 SmallVector<unsigned, 2> Excluded;
17067 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17068 Excluded.push_back(M2);
17069 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17070 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17071 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17072 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17073 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17074 << getListOfPossibleValues(OMPC_schedule,
17075 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17076 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17077 Excluded)
17078 << getOpenMPClauseName(OMPC_schedule);
17079 return true;
17080 }
17081 return false;
17082}
17083
17084OMPClause *Sema::ActOnOpenMPScheduleClause(
17085 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17086 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17087 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17088 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17089 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17090 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17091 return nullptr;
17092 // OpenMP, 2.7.1, Loop Construct, Restrictions
17093 // Either the monotonic modifier or the nonmonotonic modifier can be specified
17094 // but not both.
17095 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17096 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17097 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17098 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17099 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17100 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17101 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17102 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17103 return nullptr;
17104 }
17105 if (Kind == OMPC_SCHEDULE_unknown) {
17106 std::string Values;
17107 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17108 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17109 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17110 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17111 Exclude);
17112 } else {
17113 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17114 /*Last=*/OMPC_SCHEDULE_unknown);
17115 }
17116 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17117 << Values << getOpenMPClauseName(OMPC_schedule);
17118 return nullptr;
17119 }
17120 // OpenMP, 2.7.1, Loop Construct, Restrictions
17121 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17122 // schedule(guided).
17123 // OpenMP 5.0 does not have this restriction.
17124 if (LangOpts.OpenMP < 50 &&
17125 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17126 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17127 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17128 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17129 diag::err_omp_schedule_nonmonotonic_static);
17130 return nullptr;
17131 }
17132 Expr *ValExpr = ChunkSize;
17133 Stmt *HelperValStmt = nullptr;
17134 if (ChunkSize) {
17135 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17136 !ChunkSize->isInstantiationDependent() &&
17137 !ChunkSize->containsUnexpandedParameterPack()) {
17138 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17139 ExprResult Val =
17140 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17141 if (Val.isInvalid())
17142 return nullptr;
17143
17144 ValExpr = Val.get();
17145
17146 // OpenMP [2.7.1, Restrictions]
17147 // chunk_size must be a loop invariant integer expression with a positive
17148 // value.
17149 if (Optional<llvm::APSInt> Result =
17150 ValExpr->getIntegerConstantExpr(Context)) {
17151 if (Result->isSigned() && !Result->isStrictlyPositive()) {
17152 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17153 << "schedule" << 1 << ChunkSize->getSourceRange();
17154 return nullptr;
17155 }
17156 } else if (getOpenMPCaptureRegionForClause(
17157 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
17158 LangOpts.OpenMP) != OMPD_unknown &&
17159 !CurContext->isDependentContext()) {
17160 ValExpr = MakeFullExpr(ValExpr).get();
17161 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17162 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17163 HelperValStmt = buildPreInits(Context, Captures);
17164 }
17165 }
17166 }
17167
17168 return new (Context)
17169 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17170 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17171}
17172
17173OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17174 SourceLocation StartLoc,
17175 SourceLocation EndLoc) {
17176 OMPClause *Res = nullptr;
17177 switch (Kind) {
17178 case OMPC_ordered:
17179 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17180 break;
17181 case OMPC_nowait:
17182 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17183 break;
17184 case OMPC_untied:
17185 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17186 break;
17187 case OMPC_mergeable:
17188 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17189 break;
17190 case OMPC_read:
17191 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17192 break;
17193 case OMPC_write:
17194 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17195 break;
17196 case OMPC_update:
17197 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17198 break;
17199 case OMPC_capture:
17200 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17201 break;
17202 case OMPC_compare:
17203 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17204 break;
17205 case OMPC_seq_cst:
17206 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17207 break;
17208 case OMPC_acq_rel:
17209 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17210 break;
17211 case OMPC_acquire:
17212 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17213 break;
17214 case OMPC_release:
17215 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17216 break;
17217 case OMPC_relaxed:
17218 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17219 break;
17220 case OMPC_threads:
17221 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17222 break;
17223 case OMPC_simd:
17224 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17225 break;
17226 case OMPC_nogroup:
17227 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17228 break;
17229 case OMPC_unified_address:
17230 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17231 break;
17232 case OMPC_unified_shared_memory:
17233 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17234 break;
17235 case OMPC_reverse_offload:
17236 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17237 break;
17238 case OMPC_dynamic_allocators:
17239 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17240 break;
17241 case OMPC_destroy:
17242 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17243 /*LParenLoc=*/SourceLocation(),
17244 /*VarLoc=*/SourceLocation(), EndLoc);
17245 break;
17246 case OMPC_full:
17247 Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17248 break;
17249 case OMPC_partial:
17250 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17251 break;
17252 case OMPC_if:
17253 case OMPC_final:
17254 case OMPC_num_threads:
17255 case OMPC_safelen:
17256 case OMPC_simdlen:
17257 case OMPC_sizes:
17258 case OMPC_allocator:
17259 case OMPC_collapse:
17260 case OMPC_schedule:
17261 case OMPC_private:
17262 case OMPC_firstprivate:
17263 case OMPC_lastprivate:
17264 case OMPC_shared:
17265 case OMPC_reduction:
17266 case OMPC_task_reduction:
17267 case OMPC_in_reduction:
17268 case OMPC_linear:
17269 case OMPC_aligned:
17270 case OMPC_copyin:
17271 case OMPC_copyprivate:
17272 case OMPC_default:
17273 case OMPC_proc_bind:
17274 case OMPC_threadprivate:
17275 case OMPC_allocate:
17276 case OMPC_flush:
17277 case OMPC_depobj:
17278 case OMPC_depend:
17279 case OMPC_device:
17280 case OMPC_map:
17281 case OMPC_num_teams:
17282 case OMPC_thread_limit:
17283 case OMPC_priority:
17284 case OMPC_grainsize:
17285 case OMPC_num_tasks:
17286 case OMPC_hint:
17287 case OMPC_dist_schedule:
17288 case OMPC_defaultmap:
17289 case OMPC_unknown:
17290 case OMPC_uniform:
17291 case OMPC_to:
17292 case OMPC_from:
17293 case OMPC_use_device_ptr:
17294 case OMPC_use_device_addr:
17295 case OMPC_is_device_ptr:
17296 case OMPC_has_device_addr:
17297 case OMPC_atomic_default_mem_order:
17298 case OMPC_device_type:
17299 case OMPC_match:
17300 case OMPC_nontemporal:
17301 case OMPC_order:
17302 case OMPC_at:
17303 case OMPC_severity:
17304 case OMPC_message:
17305 case OMPC_novariants:
17306 case OMPC_nocontext:
17307 case OMPC_detach:
17308 case OMPC_inclusive:
17309 case OMPC_exclusive:
17310 case OMPC_uses_allocators:
17311 case OMPC_affinity:
17312 case OMPC_when:
17313 default:
17314 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 17314)
;
17315 }
17316 return Res;
17317}
17318
17319OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17320 SourceLocation EndLoc) {
17321 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
17322 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17323}
17324
17325OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17326 SourceLocation EndLoc) {
17327 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setUntiedRegion();
17328 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17329}
17330
17331OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17332 SourceLocation EndLoc) {
17333 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17334}
17335
17336OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17337 SourceLocation EndLoc) {
17338 return new (Context) OMPReadClause(StartLoc, EndLoc);
17339}
17340
17341OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17342 SourceLocation EndLoc) {
17343 return new (Context) OMPWriteClause(StartLoc, EndLoc);
17344}
17345
17346OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17347 SourceLocation EndLoc) {
17348 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17349}
17350
17351OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17352 SourceLocation EndLoc) {
17353 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17354}
17355
17356OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17357 SourceLocation EndLoc) {
17358 return new (Context) OMPCompareClause(StartLoc, EndLoc);
17359}
17360
17361OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17362 SourceLocation EndLoc) {
17363 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17364}
17365
17366OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17367 SourceLocation EndLoc) {
17368 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17369}
17370
17371OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17372 SourceLocation EndLoc) {
17373 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17374}
17375
17376OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17377 SourceLocation EndLoc) {
17378 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17379}
17380
17381OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17382 SourceLocation EndLoc) {
17383 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17384}
17385
17386OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17387 SourceLocation EndLoc) {
17388 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17389}
17390
17391OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17392 SourceLocation EndLoc) {
17393 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17394}
17395
17396OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17397 SourceLocation EndLoc) {
17398 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17399}
17400
17401OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17402 SourceLocation EndLoc) {
17403 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17404}
17405
17406OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17407 SourceLocation EndLoc) {
17408 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17409}
17410
17411OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17412 SourceLocation EndLoc) {
17413 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17414}
17415
17416OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17417 SourceLocation EndLoc) {
17418 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17419}
17420
17421StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17422 SourceLocation StartLoc,
17423 SourceLocation EndLoc) {
17424
17425 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17426 // At least one action-clause must appear on a directive.
17427 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17428 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17429 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17430 << Expected << getOpenMPDirectiveName(OMPD_interop);
17431 return StmtError();
17432 }
17433
17434 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17435 // A depend clause can only appear on the directive if a targetsync
17436 // interop-type is present or the interop-var was initialized with
17437 // the targetsync interop-type.
17438
17439 // If there is any 'init' clause diagnose if there is no 'init' clause with
17440 // interop-type of 'targetsync'. Cases involving other directives cannot be
17441 // diagnosed.
17442 const OMPDependClause *DependClause = nullptr;
17443 bool HasInitClause = false;
17444 bool IsTargetSync = false;
17445 for (const OMPClause *C : Clauses) {
17446 if (IsTargetSync)
17447 break;
17448 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17449 HasInitClause = true;
17450 if (InitClause->getIsTargetSync())
17451 IsTargetSync = true;
17452 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17453 DependClause = DC;
17454 }
17455 }
17456 if (DependClause && HasInitClause && !IsTargetSync) {
17457 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17458 return StmtError();
17459 }
17460
17461 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17462 // Each interop-var may be specified for at most one action-clause of each
17463 // interop construct.
17464 llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17465 for (OMPClause *C : Clauses) {
17466 OpenMPClauseKind ClauseKind = C->getClauseKind();
17467 std::pair<ValueDecl *, bool> DeclResult;
17468 SourceLocation ELoc;
17469 SourceRange ERange;
17470
17471 if (ClauseKind == OMPC_init) {
17472 auto *E = cast<OMPInitClause>(C)->getInteropVar();
17473 DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17474 } else if (ClauseKind == OMPC_use) {
17475 auto *E = cast<OMPUseClause>(C)->getInteropVar();
17476 DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17477 } else if (ClauseKind == OMPC_destroy) {
17478 auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17479 DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17480 }
17481
17482 if (DeclResult.first) {
17483 if (!InteropVars.insert(DeclResult.first).second) {
17484 Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17485 << DeclResult.first;
17486 return StmtError();
17487 }
17488 }
17489 }
17490
17491 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17492}
17493
17494static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17495 SourceLocation VarLoc,
17496 OpenMPClauseKind Kind) {
17497 SourceLocation ELoc;
17498 SourceRange ERange;
17499 Expr *RefExpr = InteropVarExpr;
17500 auto Res =
17501 getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17502 /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17503
17504 if (Res.second) {
17505 // It will be analyzed later.
17506 return true;
17507 }
17508
17509 if (!Res.first)
17510 return false;
17511
17512 // Interop variable should be of type omp_interop_t.
17513 bool HasError = false;
17514 QualType InteropType;
17515 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17516 VarLoc, Sema::LookupOrdinaryName);
17517 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17518 NamedDecl *ND = Result.getFoundDecl();
17519 if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17520 InteropType = QualType(TD->getTypeForDecl(), 0);
17521 } else {
17522 HasError = true;
17523 }
17524 } else {
17525 HasError = true;
17526 }
17527
17528 if (HasError) {
17529 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17530 << "omp_interop_t";
17531 return false;
17532 }
17533
17534 QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17535 if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17536 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17537 return false;
17538 }
17539
17540 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17541 // The interop-var passed to init or destroy must be non-const.
17542 if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17543 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17544 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17545 << /*non-const*/ 1;
17546 return false;
17547 }
17548 return true;
17549}
17550
17551OMPClause *
17552Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17553 SourceLocation StartLoc, SourceLocation LParenLoc,
17554 SourceLocation VarLoc, SourceLocation EndLoc) {
17555
17556 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17557 return nullptr;
17558
17559 // Check prefer_type values. These foreign-runtime-id values are either
17560 // string literals or constant integral expressions.
17561 for (const Expr *E : InteropInfo.PreferTypes) {
17562 if (E->isValueDependent() || E->isTypeDependent() ||
17563 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17564 continue;
17565 if (E->isIntegerConstantExpr(Context))
17566 continue;
17567 if (isa<StringLiteral>(E))
17568 continue;
17569 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17570 return nullptr;
17571 }
17572
17573 return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17574 LParenLoc, VarLoc, EndLoc);
17575}
17576
17577OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17578 SourceLocation LParenLoc,
17579 SourceLocation VarLoc,
17580 SourceLocation EndLoc) {
17581
17582 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17583 return nullptr;
17584
17585 return new (Context)
17586 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17587}
17588
17589OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17590 SourceLocation StartLoc,
17591 SourceLocation LParenLoc,
17592 SourceLocation VarLoc,
17593 SourceLocation EndLoc) {
17594 if (InteropVar &&
17595 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
17596 return nullptr;
17597
17598 return new (Context)
17599 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17600}
17601
17602OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
17603 SourceLocation StartLoc,
17604 SourceLocation LParenLoc,
17605 SourceLocation EndLoc) {
17606 Expr *ValExpr = Condition;
17607 Stmt *HelperValStmt = nullptr;
17608 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17609 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17610 !Condition->isInstantiationDependent() &&
17611 !Condition->containsUnexpandedParameterPack()) {
17612 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17613 if (Val.isInvalid())
17614 return nullptr;
17615
17616 ValExpr = MakeFullExpr(Val.get()).get();
17617
17618 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17619 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17620 LangOpts.OpenMP);
17621 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17622 ValExpr = MakeFullExpr(ValExpr).get();
17623 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17624 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17625 HelperValStmt = buildPreInits(Context, Captures);
17626 }
17627 }
17628
17629 return new (Context) OMPNovariantsClause(
17630 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17631}
17632
17633OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
17634 SourceLocation StartLoc,
17635 SourceLocation LParenLoc,
17636 SourceLocation EndLoc) {
17637 Expr *ValExpr = Condition;
17638 Stmt *HelperValStmt = nullptr;
17639 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17640 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17641 !Condition->isInstantiationDependent() &&
17642 !Condition->containsUnexpandedParameterPack()) {
17643 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17644 if (Val.isInvalid())
17645 return nullptr;
17646
17647 ValExpr = MakeFullExpr(Val.get()).get();
17648
17649 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17650 CaptureRegion =
17651 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
17652 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17653 ValExpr = MakeFullExpr(ValExpr).get();
17654 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17655 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17656 HelperValStmt = buildPreInits(Context, Captures);
17657 }
17658 }
17659
17660 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
17661 StartLoc, LParenLoc, EndLoc);
17662}
17663
17664OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
17665 SourceLocation StartLoc,
17666 SourceLocation LParenLoc,
17667 SourceLocation EndLoc) {
17668 Expr *ValExpr = ThreadID;
17669 Stmt *HelperValStmt = nullptr;
17670
17671 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17672 OpenMPDirectiveKind CaptureRegion =
17673 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
17674 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17675 ValExpr = MakeFullExpr(ValExpr).get();
17676 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17677 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17678 HelperValStmt = buildPreInits(Context, Captures);
17679 }
17680
17681 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
17682 StartLoc, LParenLoc, EndLoc);
17683}
17684
17685OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
17686 ArrayRef<Expr *> VarList,
17687 const OMPVarListLocTy &Locs,
17688 OpenMPVarListDataTy &Data) {
17689 SourceLocation StartLoc = Locs.StartLoc;
17690 SourceLocation LParenLoc = Locs.LParenLoc;
17691 SourceLocation EndLoc = Locs.EndLoc;
17692 OMPClause *Res = nullptr;
17693 int ExtraModifier = Data.ExtraModifier;
17694 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
17695 SourceLocation ColonLoc = Data.ColonLoc;
17696 switch (Kind) {
17697 case OMPC_private:
17698 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17699 break;
17700 case OMPC_firstprivate:
17701 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17702 break;
17703 case OMPC_lastprivate:
17704 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", 17705, __extension__ __PRETTY_FUNCTION__
))
17705 "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", 17705, __extension__ __PRETTY_FUNCTION__
))
;
17706 Res = ActOnOpenMPLastprivateClause(
17707 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
17708 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17709 break;
17710 case OMPC_shared:
17711 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
17712 break;
17713 case OMPC_reduction:
17714 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", 17715, __extension__ __PRETTY_FUNCTION__
))
17715 "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", 17715, __extension__ __PRETTY_FUNCTION__
))
;
17716 Res = ActOnOpenMPReductionClause(
17717 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
17718 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17719 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17720 break;
17721 case OMPC_task_reduction:
17722 Res = ActOnOpenMPTaskReductionClause(
17723 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17724 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17725 break;
17726 case OMPC_in_reduction:
17727 Res = ActOnOpenMPInReductionClause(
17728 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17729 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17730 break;
17731 case OMPC_linear:
17732 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", 17733, __extension__ __PRETTY_FUNCTION__
))
17733 "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", 17733, __extension__ __PRETTY_FUNCTION__
))
;
17734 Res = ActOnOpenMPLinearClause(
17735 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
17736 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
17737 ColonLoc, EndLoc);
17738 break;
17739 case OMPC_aligned:
17740 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
17741 LParenLoc, ColonLoc, EndLoc);
17742 break;
17743 case OMPC_copyin:
17744 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
17745 break;
17746 case OMPC_copyprivate:
17747 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17748 break;
17749 case OMPC_flush:
17750 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
17751 break;
17752 case OMPC_depend:
17753 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", 17754, __extension__ __PRETTY_FUNCTION__
))
17754 "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", 17754, __extension__ __PRETTY_FUNCTION__
))
;
17755 Res = ActOnOpenMPDependClause(
17756 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
17757 ColonLoc, Data.OmpAllMemoryLoc},
17758 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
17759 break;
17760 case OMPC_map:
17761 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", 17762, __extension__ __PRETTY_FUNCTION__
))
17762 "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", 17762, __extension__ __PRETTY_FUNCTION__
))
;
17763 Res = ActOnOpenMPMapClause(
17764 Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
17765 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
17766 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
17767 ExtraModifierLoc, ColonLoc, VarList, Locs);
17768 break;
17769 case OMPC_to:
17770 Res =
17771 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17772 Data.ReductionOrMapperIdScopeSpec,
17773 Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
17774 break;
17775 case OMPC_from:
17776 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17777 Data.ReductionOrMapperIdScopeSpec,
17778 Data.ReductionOrMapperId, ColonLoc, VarList,
17779 Locs);
17780 break;
17781 case OMPC_use_device_ptr:
17782 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17783 break;
17784 case OMPC_use_device_addr:
17785 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17786 break;
17787 case OMPC_is_device_ptr:
17788 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17789 break;
17790 case OMPC_has_device_addr:
17791 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17792 break;
17793 case OMPC_allocate:
17794 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
17795 LParenLoc, ColonLoc, EndLoc);
17796 break;
17797 case OMPC_nontemporal:
17798 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17799 break;
17800 case OMPC_inclusive:
17801 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17802 break;
17803 case OMPC_exclusive:
17804 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17805 break;
17806 case OMPC_affinity:
17807 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17808 Data.DepModOrTailExpr, VarList);
17809 break;
17810 case OMPC_if:
17811 case OMPC_depobj:
17812 case OMPC_final:
17813 case OMPC_num_threads:
17814 case OMPC_safelen:
17815 case OMPC_simdlen:
17816 case OMPC_sizes:
17817 case OMPC_allocator:
17818 case OMPC_collapse:
17819 case OMPC_default:
17820 case OMPC_proc_bind:
17821 case OMPC_schedule:
17822 case OMPC_ordered:
17823 case OMPC_nowait:
17824 case OMPC_untied:
17825 case OMPC_mergeable:
17826 case OMPC_threadprivate:
17827 case OMPC_read:
17828 case OMPC_write:
17829 case OMPC_update:
17830 case OMPC_capture:
17831 case OMPC_compare:
17832 case OMPC_seq_cst:
17833 case OMPC_acq_rel:
17834 case OMPC_acquire:
17835 case OMPC_release:
17836 case OMPC_relaxed:
17837 case OMPC_device:
17838 case OMPC_threads:
17839 case OMPC_simd:
17840 case OMPC_num_teams:
17841 case OMPC_thread_limit:
17842 case OMPC_priority:
17843 case OMPC_grainsize:
17844 case OMPC_nogroup:
17845 case OMPC_num_tasks:
17846 case OMPC_hint:
17847 case OMPC_dist_schedule:
17848 case OMPC_defaultmap:
17849 case OMPC_unknown:
17850 case OMPC_uniform:
17851 case OMPC_unified_address:
17852 case OMPC_unified_shared_memory:
17853 case OMPC_reverse_offload:
17854 case OMPC_dynamic_allocators:
17855 case OMPC_atomic_default_mem_order:
17856 case OMPC_device_type:
17857 case OMPC_match:
17858 case OMPC_order:
17859 case OMPC_at:
17860 case OMPC_severity:
17861 case OMPC_message:
17862 case OMPC_destroy:
17863 case OMPC_novariants:
17864 case OMPC_nocontext:
17865 case OMPC_detach:
17866 case OMPC_uses_allocators:
17867 case OMPC_when:
17868 case OMPC_bind:
17869 default:
17870 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "clang/lib/Sema/SemaOpenMP.cpp"
, 17870)
;
17871 }
17872 return Res;
17873}
17874
17875ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
17876 ExprObjectKind OK, SourceLocation Loc) {
17877 ExprResult Res = BuildDeclRefExpr(
17878 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17879 if (!Res.isUsable())
17880 return ExprError();
17881 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17882 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17883 if (!Res.isUsable())
17884 return ExprError();
17885 }
17886 if (VK != VK_LValue && Res.get()->isGLValue()) {
17887 Res = DefaultLvalueConversion(Res.get());
17888 if (!Res.isUsable())
17889 return ExprError();
17890 }
17891 return Res;
17892}
17893
17894OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
17895 SourceLocation StartLoc,
17896 SourceLocation LParenLoc,
17897 SourceLocation EndLoc) {
17898 SmallVector<Expr *, 8> Vars;
17899 SmallVector<Expr *, 8> PrivateCopies;
17900 bool IsImplicitClause =
17901 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17902 for (Expr *RefExpr : VarList) {
17903 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", 17903, __extension__ __PRETTY_FUNCTION__
))
;
17904 SourceLocation ELoc;
17905 SourceRange ERange;
17906 Expr *SimpleRefExpr = RefExpr;
17907 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17908 if (Res.second) {
17909 // It will be analyzed later.
17910 Vars.push_back(RefExpr);
17911 PrivateCopies.push_back(nullptr);
17912 }
17913 ValueDecl *D = Res.first;
17914 if (!D)
17915 continue;
17916
17917 QualType Type = D->getType();
17918 auto *VD = dyn_cast<VarDecl>(D);
17919
17920 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17921 // A variable that appears in a private clause must not have an incomplete
17922 // type or a reference type.
17923 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
17924 continue;
17925 Type = Type.getNonReferenceType();
17926
17927 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17928 // A variable that is privatized must not have a const-qualified type
17929 // unless it is of class type with a mutable member. This restriction does
17930 // not apply to the firstprivate clause.
17931 //
17932 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17933 // A variable that appears in a private clause must not have a
17934 // const-qualified type unless it is of class type with a mutable member.
17935 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
17936 continue;
17937
17938 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17939 // in a Construct]
17940 // Variables with the predetermined data-sharing attributes may not be
17941 // listed in data-sharing attributes clauses, except for the cases
17942 // listed below. For these exceptions only, listing a predetermined
17943 // variable in a data-sharing attribute clause is allowed and overrides
17944 // the variable's predetermined data-sharing attributes.
17945 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17946 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17947 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17948 << getOpenMPClauseName(OMPC_private);
17949 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17950 continue;
17951 }
17952
17953 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17954 // Variably modified types are not supported for tasks.
17955 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17956 isOpenMPTaskingDirective(CurrDir)) {
17957 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17958 << getOpenMPClauseName(OMPC_private) << Type
17959 << getOpenMPDirectiveName(CurrDir);
17960 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17961 VarDecl::DeclarationOnly;
17962 Diag(D->getLocation(),
17963 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17964 << D;
17965 continue;
17966 }
17967
17968 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17969 // A list item cannot appear in both a map clause and a data-sharing
17970 // attribute clause on the same construct
17971 //
17972 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17973 // A list item cannot appear in both a map clause and a data-sharing
17974 // attribute clause on the same construct unless the construct is a
17975 // combined construct.
17976 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
17977 CurrDir == OMPD_target) {
17978 OpenMPClauseKind ConflictKind;
17979 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
17980 VD, /*CurrentRegionOnly=*/true,
17981 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
17982 OpenMPClauseKind WhereFoundClauseKind) -> bool {
17983 ConflictKind = WhereFoundClauseKind;
17984 return true;
17985 })) {
17986 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17987 << getOpenMPClauseName(OMPC_private)
17988 << getOpenMPClauseName(ConflictKind)
17989 << getOpenMPDirectiveName(CurrDir);
17990 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17991 continue;
17992 }
17993 }
17994
17995 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17996 // A variable of class type (or array thereof) that appears in a private
17997 // clause requires an accessible, unambiguous default constructor for the
17998 // class type.
17999 // Generate helper private variable and initialize it with the default
18000 // value. The address of the original variable is replaced by the address of
18001 // the new private variable in CodeGen. This new variable is not added to
18002 // IdResolver, so the code in the OpenMP region uses original variable for
18003 // proper diagnostics.
18004 Type = Type.getUnqualifiedType();
18005 VarDecl *VDPrivate =
18006 buildVarDecl(*this, ELoc, Type, D->getName(),
18007 D->hasAttrs() ? &D->getAttrs() : nullptr,
18008 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18009 ActOnUninitializedDecl(VDPrivate);
18010 if (VDPrivate->isInvalidDecl())
18011 continue;
18012 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18013 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18014
18015 DeclRefExpr *Ref = nullptr;
18016 if (!VD && !CurContext->isDependentContext()) {
18017 auto *FD = dyn_cast<FieldDecl>(D);
18018 VarDecl *VD = FD ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitFDCapExprDecl(FD) : nullptr;
18019 if (VD)
18020 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18021 RefExpr->getExprLoc());
18022 else
18023 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18024 }
18025 if (!IsImplicitClause)
18026 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18027 Vars.push_back((VD || CurContext->isDependentContext())
18028 ? RefExpr->IgnoreParens()
18029 : Ref);
18030 PrivateCopies.push_back(VDPrivateRefExpr);
18031 }
18032
18033 if (Vars.empty())
18034 return nullptr;
18035
18036 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18037 PrivateCopies);
18038}
18039
18040OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18041 SourceLocation StartLoc,
18042 SourceLocation LParenLoc,
18043 SourceLocation EndLoc) {
18044 SmallVector<Expr *, 8> Vars;
18045 SmallVector<Expr *, 8> PrivateCopies;
18046 SmallVector<Expr *, 8> Inits;
18047 SmallVector<Decl *, 4> ExprCaptures;
18048 bool IsImplicitClause =
18049 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18050 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
18051
18052 for (Expr *RefExpr : VarList) {
18053 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", 18053, __extension__ __PRETTY_FUNCTION__
))
;
18054 SourceLocation ELoc;
18055 SourceRange ERange;
18056 Expr *SimpleRefExpr = RefExpr;
18057 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18058 if (Res.second) {
18059 // It will be analyzed later.
18060 Vars.push_back(RefExpr);
18061 PrivateCopies.push_back(nullptr);
18062 Inits.push_back(nullptr);
18063 }
18064 ValueDecl *D = Res.first;
18065 if (!D)
18066 continue;
18067
18068 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18069 QualType Type = D->getType();
18070 auto *VD = dyn_cast<VarDecl>(D);
18071
18072 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18073 // A variable that appears in a private clause must not have an incomplete
18074 // type or a reference type.
18075 if (RequireCompleteType(ELoc, Type,
18076 diag::err_omp_firstprivate_incomplete_type))
18077 continue;
18078 Type = Type.getNonReferenceType();
18079
18080 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18081 // A variable of class type (or array thereof) that appears in a private
18082 // clause requires an accessible, unambiguous copy constructor for the
18083 // class type.
18084 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18085
18086 // If an implicit firstprivate variable found it was checked already.
18087 DSAStackTy::DSAVarData TopDVar;
18088 if (!IsImplicitClause) {
18089 DSAStackTy::DSAVarData DVar =
18090 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18091 TopDVar = DVar;
18092 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18093 bool IsConstant = ElemType.isConstant(Context);
18094 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18095 // A list item that specifies a given variable may not appear in more
18096 // than one clause on the same directive, except that a variable may be
18097 // specified in both firstprivate and lastprivate clauses.
18098 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18099 // A list item may appear in a firstprivate or lastprivate clause but not
18100 // both.
18101 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18102 (isOpenMPDistributeDirective(CurrDir) ||
18103 DVar.CKind != OMPC_lastprivate) &&
18104 DVar.RefExpr) {
18105 Diag(ELoc, diag::err_omp_wrong_dsa)
18106 << getOpenMPClauseName(DVar.CKind)
18107 << getOpenMPClauseName(OMPC_firstprivate);
18108 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18109 continue;
18110 }
18111
18112 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18113 // in a Construct]
18114 // Variables with the predetermined data-sharing attributes may not be
18115 // listed in data-sharing attributes clauses, except for the cases
18116 // listed below. For these exceptions only, listing a predetermined
18117 // variable in a data-sharing attribute clause is allowed and overrides
18118 // the variable's predetermined data-sharing attributes.
18119 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18120 // in a Construct, C/C++, p.2]
18121 // Variables with const-qualified type having no mutable member may be
18122 // listed in a firstprivate clause, even if they are static data members.
18123 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18124 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18125 Diag(ELoc, diag::err_omp_wrong_dsa)
18126 << getOpenMPClauseName(DVar.CKind)
18127 << getOpenMPClauseName(OMPC_firstprivate);
18128 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18129 continue;
18130 }
18131
18132 // OpenMP [2.9.3.4, Restrictions, p.2]
18133 // A list item that is private within a parallel region must not appear
18134 // in a firstprivate clause on a worksharing construct if any of the
18135 // worksharing regions arising from the worksharing construct ever bind
18136 // to any of the parallel regions arising from the parallel construct.
18137 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18138 // A list item that is private within a teams region must not appear in a
18139 // firstprivate clause on a distribute construct if any of the distribute
18140 // regions arising from the distribute construct ever bind to any of the
18141 // teams regions arising from the teams construct.
18142 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18143 // A list item that appears in a reduction clause of a teams construct
18144 // must not appear in a firstprivate clause on a distribute construct if
18145 // any of the distribute regions arising from the distribute construct
18146 // ever bind to any of the teams regions arising from the teams construct.
18147 if ((isOpenMPWorksharingDirective(CurrDir) ||
18148 isOpenMPDistributeDirective(CurrDir)) &&
18149 !isOpenMPParallelDirective(CurrDir) &&
18150 !isOpenMPTeamsDirective(CurrDir)) {
18151 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
18152 if (DVar.CKind != OMPC_shared &&
18153 (isOpenMPParallelDirective(DVar.DKind) ||
18154 isOpenMPTeamsDirective(DVar.DKind) ||
18155 DVar.DKind == OMPD_unknown)) {
18156 Diag(ELoc, diag::err_omp_required_access)
18157 << getOpenMPClauseName(OMPC_firstprivate)
18158 << getOpenMPClauseName(OMPC_shared);
18159 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18160 continue;
18161 }
18162 }
18163 // OpenMP [2.9.3.4, Restrictions, p.3]
18164 // A list item that appears in a reduction clause of a parallel construct
18165 // must not appear in a firstprivate clause on a worksharing or task
18166 // construct if any of the worksharing or task regions arising from the
18167 // worksharing or task construct ever bind to any of the parallel regions
18168 // arising from the parallel construct.
18169 // OpenMP [2.9.3.4, Restrictions, p.4]
18170 // A list item that appears in a reduction clause in worksharing
18171 // construct must not appear in a firstprivate clause in a task construct
18172 // encountered during execution of any of the worksharing regions arising
18173 // from the worksharing construct.
18174 if (isOpenMPTaskingDirective(CurrDir)) {
18175 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
18176 D,
18177 [](OpenMPClauseKind C, bool AppliedToPointee) {
18178 return C == OMPC_reduction && !AppliedToPointee;
18179 },
18180 [](OpenMPDirectiveKind K) {
18181 return isOpenMPParallelDirective(K) ||
18182 isOpenMPWorksharingDirective(K) ||
18183 isOpenMPTeamsDirective(K);
18184 },
18185 /*FromParent=*/true);
18186 if (DVar.CKind == OMPC_reduction &&
18187 (isOpenMPParallelDirective(DVar.DKind) ||
18188 isOpenMPWorksharingDirective(DVar.DKind) ||
18189 isOpenMPTeamsDirective(DVar.DKind))) {
18190 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18191 << getOpenMPDirectiveName(DVar.DKind);
18192 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18193 continue;
18194 }
18195 }
18196
18197 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18198 // A list item cannot appear in both a map clause and a data-sharing
18199 // attribute clause on the same construct
18200 //
18201 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18202 // A list item cannot appear in both a map clause and a data-sharing
18203 // attribute clause on the same construct unless the construct is a
18204 // combined construct.
18205 if ((LangOpts.OpenMP <= 45 &&
18206 isOpenMPTargetExecutionDirective(CurrDir)) ||
18207 CurrDir == OMPD_target) {
18208 OpenMPClauseKind ConflictKind;
18209 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
18210 VD, /*CurrentRegionOnly=*/true,
18211 [&ConflictKind](
18212 OMPClauseMappableExprCommon::MappableExprComponentListRef,
18213 OpenMPClauseKind WhereFoundClauseKind) {
18214 ConflictKind = WhereFoundClauseKind;
18215 return true;
18216 })) {
18217 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18218 << getOpenMPClauseName(OMPC_firstprivate)
18219 << getOpenMPClauseName(ConflictKind)
18220 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18221 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18222 continue;
18223 }
18224 }
18225 }
18226
18227 // Variably modified types are not supported for tasks.
18228 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18229 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
18230 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18231 << getOpenMPClauseName(OMPC_firstprivate) << Type
18232 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18233 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18234 VarDecl::DeclarationOnly;
18235 Diag(D->getLocation(),
18236 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18237 << D;
18238 continue;
18239 }
18240
18241 Type = Type.getUnqualifiedType();
18242 VarDecl *VDPrivate =
18243 buildVarDecl(*this, ELoc, Type, D->getName(),
18244 D->hasAttrs() ? &D->getAttrs() : nullptr,
18245 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18246 // Generate helper private variable and initialize it with the value of the
18247 // original variable. The address of the original variable is replaced by
18248 // the address of the new private variable in the CodeGen. This new variable
18249 // is not added to IdResolver, so the code in the OpenMP region uses
18250 // original variable for proper diagnostics and variable capturing.
18251 Expr *VDInitRefExpr = nullptr;
18252 // For arrays generate initializer for single element and replace it by the
18253 // original array element in CodeGen.
18254 if (Type->isArrayType()) {
18255 VarDecl *VDInit =
18256 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18257 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18258 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18259 ElemType = ElemType.getUnqualifiedType();
18260 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18261 ".firstprivate.temp");
18262 InitializedEntity Entity =
18263 InitializedEntity::InitializeVariable(VDInitTemp);
18264 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18265
18266 InitializationSequence InitSeq(*this, Entity, Kind, Init);
18267 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18268 if (Result.isInvalid())
18269 VDPrivate->setInvalidDecl();
18270 else
18271 VDPrivate->setInit(Result.getAs<Expr>());
18272 // Remove temp variable declaration.
18273 Context.Deallocate(VDInitTemp);
18274 } else {
18275 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18276 ".firstprivate.temp");
18277 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18278 RefExpr->getExprLoc());
18279 AddInitializerToDecl(VDPrivate,
18280 DefaultLvalueConversion(VDInitRefExpr).get(),
18281 /*DirectInit=*/false);
18282 }
18283 if (VDPrivate->isInvalidDecl()) {
18284 if (IsImplicitClause) {
18285 Diag(RefExpr->getExprLoc(),
18286 diag::note_omp_task_predetermined_firstprivate_here);
18287 }
18288 continue;
18289 }
18290 CurContext->addDecl(VDPrivate);
18291 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18292 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18293 RefExpr->getExprLoc());
18294 DeclRefExpr *Ref = nullptr;
18295 if (!VD && !CurContext->isDependentContext()) {
18296 if (TopDVar.CKind == OMPC_lastprivate) {
18297 Ref = TopDVar.PrivateCopy;
18298 } else {
18299 auto *FD = dyn_cast<FieldDecl>(D);
18300 VarDecl *VD = FD ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitFDCapExprDecl(FD) : nullptr;
18301 if (VD)
18302 Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18303 RefExpr->getExprLoc());
18304 else
18305 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18306 if (VD || !isOpenMPCapturedDecl(D))
18307 ExprCaptures.push_back(Ref->getDecl());
18308 }
18309 }
18310 if (!IsImplicitClause)
18311 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18312 Vars.push_back((VD || CurContext->isDependentContext())
18313 ? RefExpr->IgnoreParens()
18314 : Ref);
18315 PrivateCopies.push_back(VDPrivateRefExpr);
18316 Inits.push_back(VDInitRefExpr);
18317 }
18318
18319 if (Vars.empty())
18320 return nullptr;
18321
18322 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18323 Vars, PrivateCopies, Inits,
18324 buildPreInits(Context, ExprCaptures));
18325}
18326
18327OMPClause *Sema::ActOnOpenMPLastprivateClause(
18328 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18329 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18330 SourceLocation LParenLoc, SourceLocation EndLoc) {
18331 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18332 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", 18332, __extension__ __PRETTY_FUNCTION__
))
;
18333 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18334 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18335 /*Last=*/OMPC_LASTPRIVATE_unknown)
18336 << getOpenMPClauseName(OMPC_lastprivate);
18337 return nullptr;
18338 }
18339
18340 SmallVector<Expr *, 8> Vars;
18341 SmallVector<Expr *, 8> SrcExprs;
18342 SmallVector<Expr *, 8> DstExprs;
18343 SmallVector<Expr *, 8> AssignmentOps;
18344 SmallVector<Decl *, 4> ExprCaptures;
18345 SmallVector<Expr *, 4> ExprPostUpdates;
18346 for (Expr *RefExpr : VarList) {
18347 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", 18347, __extension__ __PRETTY_FUNCTION__
))
;
18348 SourceLocation ELoc;
18349 SourceRange ERange;
18350 Expr *SimpleRefExpr = RefExpr;
18351 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18352 if (Res.second) {
18353 // It will be analyzed later.
18354 Vars.push_back(RefExpr);
18355 SrcExprs.push_back(nullptr);
18356 DstExprs.push_back(nullptr);
18357 AssignmentOps.push_back(nullptr);
18358 }
18359 ValueDecl *D = Res.first;
18360 if (!D)
18361 continue;
18362
18363 QualType Type = D->getType();
18364 auto *VD = dyn_cast<VarDecl>(D);
18365
18366 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18367 // A variable that appears in a lastprivate clause must not have an
18368 // incomplete type or a reference type.
18369 if (RequireCompleteType(ELoc, Type,
18370 diag::err_omp_lastprivate_incomplete_type))
18371 continue;
18372 Type = Type.getNonReferenceType();
18373
18374 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18375 // A variable that is privatized must not have a const-qualified type
18376 // unless it is of class type with a mutable member. This restriction does
18377 // not apply to the firstprivate clause.
18378 //
18379 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18380 // A variable that appears in a lastprivate clause must not have a
18381 // const-qualified type unless it is of class type with a mutable member.
18382 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18383 continue;
18384
18385 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18386 // A list item that appears in a lastprivate clause with the conditional
18387 // modifier must be a scalar variable.
18388 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18389 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18390 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18391 VarDecl::DeclarationOnly;
18392 Diag(D->getLocation(),
18393 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18394 << D;
18395 continue;
18396 }
18397
18398 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18399 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18400 // in a Construct]
18401 // Variables with the predetermined data-sharing attributes may not be
18402 // listed in data-sharing attributes clauses, except for the cases
18403 // listed below.
18404 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18405 // A list item may appear in a firstprivate or lastprivate clause but not
18406 // both.
18407 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18408 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18409 (isOpenMPDistributeDirective(CurrDir) ||
18410 DVar.CKind != OMPC_firstprivate) &&
18411 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18412 Diag(ELoc, diag::err_omp_wrong_dsa)
18413 << getOpenMPClauseName(DVar.CKind)
18414 << getOpenMPClauseName(OMPC_lastprivate);
18415 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18416 continue;
18417 }
18418
18419 // OpenMP [2.14.3.5, Restrictions, p.2]
18420 // A list item that is private within a parallel region, or that appears in
18421 // the reduction clause of a parallel construct, must not appear in a
18422 // lastprivate clause on a worksharing construct if any of the corresponding
18423 // worksharing regions ever binds to any of the corresponding parallel
18424 // regions.
18425 DSAStackTy::DSAVarData TopDVar = DVar;
18426 if (isOpenMPWorksharingDirective(CurrDir) &&
18427 !isOpenMPParallelDirective(CurrDir) &&
18428 !isOpenMPTeamsDirective(CurrDir)) {
18429 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
18430 if (DVar.CKind != OMPC_shared) {
18431 Diag(ELoc, diag::err_omp_required_access)
18432 << getOpenMPClauseName(OMPC_lastprivate)
18433 << getOpenMPClauseName(OMPC_shared);
18434 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18435 continue;
18436 }
18437 }
18438
18439 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18440 // A variable of class type (or array thereof) that appears in a
18441 // lastprivate clause requires an accessible, unambiguous default
18442 // constructor for the class type, unless the list item is also specified
18443 // in a firstprivate clause.
18444 // A variable of class type (or array thereof) that appears in a
18445 // lastprivate clause requires an accessible, unambiguous copy assignment
18446 // operator for the class type.
18447 Type = Context.getBaseElementType(Type).getNonReferenceType();
18448 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18449 Type.getUnqualifiedType(), ".lastprivate.src",
18450 D->hasAttrs() ? &D->getAttrs() : nullptr);
18451 DeclRefExpr *PseudoSrcExpr =
18452 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18453 VarDecl *DstVD =
18454 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18455 D->hasAttrs() ? &D->getAttrs() : nullptr);
18456 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18457 // For arrays generate assignment operation for single element and replace
18458 // it by the original array element in CodeGen.
18459 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18460 PseudoDstExpr, PseudoSrcExpr);
18461 if (AssignmentOp.isInvalid())
18462 continue;
18463 AssignmentOp =
18464 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18465 if (AssignmentOp.isInvalid())
18466 continue;
18467
18468 DeclRefExpr *Ref = nullptr;
18469 if (!VD && !CurContext->isDependentContext()) {
18470 if (TopDVar.CKind == OMPC_firstprivate) {
18471 Ref = TopDVar.PrivateCopy;
18472 } else {
18473 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18474 if (!isOpenMPCapturedDecl(D))
18475 ExprCaptures.push_back(Ref->getDecl());
18476 }
18477 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18478 (!isOpenMPCapturedDecl(D) &&
18479 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18480 ExprResult RefRes = DefaultLvalueConversion(Ref);
18481 if (!RefRes.isUsable())
18482 continue;
18483 ExprResult PostUpdateRes =
18484 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18485 RefRes.get());
18486 if (!PostUpdateRes.isUsable())
18487 continue;
18488 ExprPostUpdates.push_back(
18489 IgnoredValueConversions(PostUpdateRes.get()).get());
18490 }
18491 }
18492 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18493 Vars.push_back((VD || CurContext->isDependentContext())
18494 ? RefExpr->IgnoreParens()
18495 : Ref);
18496 SrcExprs.push_back(PseudoSrcExpr);
18497 DstExprs.push_back(PseudoDstExpr);
18498 AssignmentOps.push_back(AssignmentOp.get());
18499 }
18500
18501 if (Vars.empty())
18502 return nullptr;
18503
18504 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18505 Vars, SrcExprs, DstExprs, AssignmentOps,
18506 LPKind, LPKindLoc, ColonLoc,
18507 buildPreInits(Context, ExprCaptures),
18508 buildPostUpdate(*this, ExprPostUpdates));
18509}
18510
18511OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18512 SourceLocation StartLoc,
18513 SourceLocation LParenLoc,
18514 SourceLocation EndLoc) {
18515 SmallVector<Expr *, 8> Vars;
18516 for (Expr *RefExpr : VarList) {
18517 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", 18517, __extension__ __PRETTY_FUNCTION__
))
;
18518 SourceLocation ELoc;
18519 SourceRange ERange;
18520 Expr *SimpleRefExpr = RefExpr;
18521 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18522 if (Res.second) {
18523 // It will be analyzed later.
18524 Vars.push_back(RefExpr);
18525 }
18526 ValueDecl *D = Res.first;
18527 if (!D)
18528 continue;
18529
18530 auto *VD = dyn_cast<VarDecl>(D);
18531 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18532 // in a Construct]
18533 // Variables with the predetermined data-sharing attributes may not be
18534 // listed in data-sharing attributes clauses, except for the cases
18535 // listed below. For these exceptions only, listing a predetermined
18536 // variable in a data-sharing attribute clause is allowed and overrides
18537 // the variable's predetermined data-sharing attributes.
18538 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18539 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18540 DVar.RefExpr) {
18541 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18542 << getOpenMPClauseName(OMPC_shared);
18543 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18544 continue;
18545 }
18546
18547 DeclRefExpr *Ref = nullptr;
18548 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18549 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18550 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18551 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18552 ? RefExpr->IgnoreParens()
18553 : Ref);
18554 }
18555
18556 if (Vars.empty())
18557 return nullptr;
18558
18559 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18560}
18561
18562namespace {
18563class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18564 DSAStackTy *Stack;
18565
18566public:
18567 bool VisitDeclRefExpr(DeclRefExpr *E) {
18568 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18569 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18570 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18571 return false;
18572 if (DVar.CKind != OMPC_unknown)
18573 return true;
18574 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18575 VD,
18576 [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18577 return isOpenMPPrivate(C) && !AppliedToPointee;
18578 },
18579 [](OpenMPDirectiveKind) { return true; },
18580 /*FromParent=*/true);
18581 return DVarPrivate.CKind != OMPC_unknown;
18582 }
18583 return false;
18584 }
18585 bool VisitStmt(Stmt *S) {
18586 for (Stmt *Child : S->children()) {
18587 if (Child && Visit(Child))
18588 return true;
18589 }
18590 return false;
18591 }
18592 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18593};
18594} // namespace
18595
18596namespace {
18597// Transform MemberExpression for specified FieldDecl of current class to
18598// DeclRefExpr to specified OMPCapturedExprDecl.
18599class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18600 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18601 ValueDecl *Field = nullptr;
18602 DeclRefExpr *CapturedExpr = nullptr;
18603
18604public:
18605 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18606 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18607
18608 ExprResult TransformMemberExpr(MemberExpr *E) {
18609 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18610 E->getMemberDecl() == Field) {
18611 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18612 return CapturedExpr;
18613 }
18614 return BaseTransform::TransformMemberExpr(E);
18615 }
18616 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18617};
18618} // namespace
18619
18620template <typename T, typename U>
18621static T filterLookupForUDReductionAndMapper(
18622 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18623 for (U &Set : Lookups) {
18624 for (auto *D : Set) {
18625 if (T Res = Gen(cast<ValueDecl>(D)))
18626 return Res;
18627 }
18628 }
18629 return T();
18630}
18631
18632static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
18633 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", 18633, __extension__ __PRETTY_FUNCTION__
))
;
18634
18635 for (auto *RD : D->redecls()) {
18636 // Don't bother with extra checks if we already know this one isn't visible.
18637 if (RD == D)
18638 continue;
18639
18640 auto ND = cast<NamedDecl>(RD);
18641 if (LookupResult::isVisible(SemaRef, ND))
18642 return ND;
18643 }
18644
18645 return nullptr;
18646}
18647
18648static void
18649argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
18650 SourceLocation Loc, QualType Ty,
18651 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18652 // Find all of the associated namespaces and classes based on the
18653 // arguments we have.
18654 Sema::AssociatedNamespaceSet AssociatedNamespaces;
18655 Sema::AssociatedClassSet AssociatedClasses;
18656 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18657 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18658 AssociatedClasses);
18659
18660 // C++ [basic.lookup.argdep]p3:
18661 // Let X be the lookup set produced by unqualified lookup (3.4.1)
18662 // and let Y be the lookup set produced by argument dependent
18663 // lookup (defined as follows). If X contains [...] then Y is
18664 // empty. Otherwise Y is the set of declarations found in the
18665 // namespaces associated with the argument types as described
18666 // below. The set of declarations found by the lookup of the name
18667 // is the union of X and Y.
18668 //
18669 // Here, we compute Y and add its members to the overloaded
18670 // candidate set.
18671 for (auto *NS : AssociatedNamespaces) {
18672 // When considering an associated namespace, the lookup is the
18673 // same as the lookup performed when the associated namespace is
18674 // used as a qualifier (3.4.3.2) except that:
18675 //
18676 // -- Any using-directives in the associated namespace are
18677 // ignored.
18678 //
18679 // -- Any namespace-scope friend functions declared in
18680 // associated classes are visible within their respective
18681 // namespaces even if they are not visible during an ordinary
18682 // lookup (11.4).
18683 DeclContext::lookup_result R = NS->lookup(Id.getName());
18684 for (auto *D : R) {
18685 auto *Underlying = D;
18686 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18687 Underlying = USD->getTargetDecl();
18688
18689 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18690 !isa<OMPDeclareMapperDecl>(Underlying))
18691 continue;
18692
18693 if (!SemaRef.isVisible(D)) {
18694 D = findAcceptableDecl(SemaRef, D);
18695 if (!D)
18696 continue;
18697 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18698 Underlying = USD->getTargetDecl();
18699 }
18700 Lookups.emplace_back();
18701 Lookups.back().addDecl(Underlying);
18702 }
18703 }
18704}
18705
18706static ExprResult
18707buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
18708 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
18709 const DeclarationNameInfo &ReductionId, QualType Ty,
18710 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
18711 if (ReductionIdScopeSpec.isInvalid())
18712 return ExprError();
18713 SmallVector<UnresolvedSet<8>, 4> Lookups;
18714 if (S) {
18715 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18716 Lookup.suppressDiagnostics();
18717 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
18718 NamedDecl *D = Lookup.getRepresentativeDecl();
18719 do {
18720 S = S->getParent();
18721 } while (S && !S->isDeclScope(D));
18722 if (S)
18723 S = S->getParent();
18724 Lookups.emplace_back();
18725 Lookups.back().append(Lookup.begin(), Lookup.end());
18726 Lookup.clear();
18727 }
18728 } else if (auto *ULE =
18729 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18730 Lookups.push_back(UnresolvedSet<8>());
18731 Decl *PrevD = nullptr;
18732 for (NamedDecl *D : ULE->decls()) {
18733 if (D == PrevD)
18734 Lookups.push_back(UnresolvedSet<8>());
18735 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18736 Lookups.back().addDecl(DRD);
18737 PrevD = D;
18738 }
18739 }
18740 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
18741 Ty->isInstantiationDependentType() ||
18742 Ty->containsUnexpandedParameterPack() ||
18743 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18744 return !D->isInvalidDecl() &&
18745 (D->getType()->isDependentType() ||
18746 D->getType()->isInstantiationDependentType() ||
18747 D->getType()->containsUnexpandedParameterPack());
18748 })) {
18749 UnresolvedSet<8> ResSet;
18750 for (const UnresolvedSet<8> &Set : Lookups) {
18751 if (Set.empty())
18752 continue;
18753 ResSet.append(Set.begin(), Set.end());
18754 // The last item marks the end of all declarations at the specified scope.
18755 ResSet.addDecl(Set[Set.size() - 1]);
18756 }
18757 return UnresolvedLookupExpr::Create(
18758 SemaRef.Context, /*NamingClass=*/nullptr,
18759 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
18760 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
18761 }
18762 // Lookup inside the classes.
18763 // C++ [over.match.oper]p3:
18764 // For a unary operator @ with an operand of a type whose
18765 // cv-unqualified version is T1, and for a binary operator @ with
18766 // a left operand of a type whose cv-unqualified version is T1 and
18767 // a right operand of a type whose cv-unqualified version is T2,
18768 // three sets of candidate functions, designated member
18769 // candidates, non-member candidates and built-in candidates, are
18770 // constructed as follows:
18771 // -- If T1 is a complete class type or a class currently being
18772 // defined, the set of member candidates is the result of the
18773 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18774 // the set of member candidates is empty.
18775 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18776 Lookup.suppressDiagnostics();
18777 if (const auto *TyRec = Ty->getAs<RecordType>()) {
18778 // Complete the type if it can be completed.
18779 // If the type is neither complete nor being defined, bail out now.
18780 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18781 TyRec->getDecl()->getDefinition()) {
18782 Lookup.clear();
18783 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
18784 if (Lookup.empty()) {
18785 Lookups.emplace_back();
18786 Lookups.back().append(Lookup.begin(), Lookup.end());
18787 }
18788 }
18789 }
18790 // Perform ADL.
18791 if (SemaRef.getLangOpts().CPlusPlus)
18792 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18793 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18794 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18795 if (!D->isInvalidDecl() &&
18796 SemaRef.Context.hasSameType(D->getType(), Ty))
18797 return D;
18798 return nullptr;
18799 }))
18800 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18801 VK_LValue, Loc);
18802 if (SemaRef.getLangOpts().CPlusPlus) {
18803 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18804 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18805 if (!D->isInvalidDecl() &&
18806 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18807 !Ty.isMoreQualifiedThan(D->getType()))
18808 return D;
18809 return nullptr;
18810 })) {
18811 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18812 /*DetectVirtual=*/false);
18813 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18814 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18815 VD->getType().getUnqualifiedType()))) {
18816 if (SemaRef.CheckBaseClassAccess(
18817 Loc, VD->getType(), Ty, Paths.front(),
18818 /*DiagID=*/0) != Sema::AR_inaccessible) {
18819 SemaRef.BuildBasePathArray(Paths, BasePath);
18820 return SemaRef.BuildDeclRefExpr(
18821 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18822 }
18823 }
18824 }
18825 }
18826 }
18827 if (ReductionIdScopeSpec.isSet()) {
18828 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18829 << Ty << Range;
18830 return ExprError();
18831 }
18832 return ExprEmpty();
18833}
18834
18835namespace {
18836/// Data for the reduction-based clauses.
18837struct ReductionData {
18838 /// List of original reduction items.
18839 SmallVector<Expr *, 8> Vars;
18840 /// List of private copies of the reduction items.
18841 SmallVector<Expr *, 8> Privates;
18842 /// LHS expressions for the reduction_op expressions.
18843 SmallVector<Expr *, 8> LHSs;
18844 /// RHS expressions for the reduction_op expressions.
18845 SmallVector<Expr *, 8> RHSs;
18846 /// Reduction operation expression.
18847 SmallVector<Expr *, 8> ReductionOps;
18848 /// inscan copy operation expressions.
18849 SmallVector<Expr *, 8> InscanCopyOps;
18850 /// inscan copy temp array expressions for prefix sums.
18851 SmallVector<Expr *, 8> InscanCopyArrayTemps;
18852 /// inscan copy temp array element expressions for prefix sums.
18853 SmallVector<Expr *, 8> InscanCopyArrayElems;
18854 /// Taskgroup descriptors for the corresponding reduction items in
18855 /// in_reduction clauses.
18856 SmallVector<Expr *, 8> TaskgroupDescriptors;
18857 /// List of captures for clause.
18858 SmallVector<Decl *, 4> ExprCaptures;
18859 /// List of postupdate expressions.
18860 SmallVector<Expr *, 4> ExprPostUpdates;
18861 /// Reduction modifier.
18862 unsigned RedModifier = 0;
18863 ReductionData() = delete;
18864 /// Reserves required memory for the reduction data.
18865 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18866 Vars.reserve(Size);
18867 Privates.reserve(Size);
18868 LHSs.reserve(Size);
18869 RHSs.reserve(Size);
18870 ReductionOps.reserve(Size);
18871 if (RedModifier == OMPC_REDUCTION_inscan) {
18872 InscanCopyOps.reserve(Size);
18873 InscanCopyArrayTemps.reserve(Size);
18874 InscanCopyArrayElems.reserve(Size);
18875 }
18876 TaskgroupDescriptors.reserve(Size);
18877 ExprCaptures.reserve(Size);
18878 ExprPostUpdates.reserve(Size);
18879 }
18880 /// Stores reduction item and reduction operation only (required for dependent
18881 /// reduction item).
18882 void push(Expr *Item, Expr *ReductionOp) {
18883 Vars.emplace_back(Item);
18884 Privates.emplace_back(nullptr);
18885 LHSs.emplace_back(nullptr);
18886 RHSs.emplace_back(nullptr);
18887 ReductionOps.emplace_back(ReductionOp);
18888 TaskgroupDescriptors.emplace_back(nullptr);
18889 if (RedModifier == OMPC_REDUCTION_inscan) {
18890 InscanCopyOps.push_back(nullptr);
18891 InscanCopyArrayTemps.push_back(nullptr);
18892 InscanCopyArrayElems.push_back(nullptr);
18893 }
18894 }
18895 /// Stores reduction data.
18896 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18897 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18898 Expr *CopyArrayElem) {
18899 Vars.emplace_back(Item);
18900 Privates.emplace_back(Private);
18901 LHSs.emplace_back(LHS);
18902 RHSs.emplace_back(RHS);
18903 ReductionOps.emplace_back(ReductionOp);
18904 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18905 if (RedModifier == OMPC_REDUCTION_inscan) {
18906 InscanCopyOps.push_back(CopyOp);
18907 InscanCopyArrayTemps.push_back(CopyArrayTemp);
18908 InscanCopyArrayElems.push_back(CopyArrayElem);
18909 } else {
18910 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", 18912, __extension__ __PRETTY_FUNCTION__
))
18911 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", 18912, __extension__ __PRETTY_FUNCTION__
))
18912 "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", 18912, __extension__ __PRETTY_FUNCTION__
))
;
18913 }
18914 }
18915};
18916} // namespace
18917
18918static bool checkOMPArraySectionConstantForReduction(
18919 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
18920 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
18921 const Expr *Length = OASE->getLength();
18922 if (Length == nullptr) {
18923 // For array sections of the form [1:] or [:], we would need to analyze
18924 // the lower bound...
18925 if (OASE->getColonLocFirst().isValid())
18926 return false;
18927
18928 // This is an array subscript which has implicit length 1!
18929 SingleElement = true;
18930 ArraySizes.push_back(llvm::APSInt::get(1));
18931 } else {
18932 Expr::EvalResult Result;
18933 if (!Length->EvaluateAsInt(Result, Context))
18934 return false;
18935
18936 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18937 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18938 ArraySizes.push_back(ConstantLengthValue);
18939 }
18940
18941 // Get the base of this array section and walk up from there.
18942 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
18943
18944 // We require length = 1 for all array sections except the right-most to
18945 // guarantee that the memory region is contiguous and has no holes in it.
18946 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
18947 Length = TempOASE->getLength();
18948 if (Length == nullptr) {
18949 // For array sections of the form [1:] or [:], we would need to analyze
18950 // the lower bound...
18951 if (OASE->getColonLocFirst().isValid())
18952 return false;
18953
18954 // This is an array subscript which has implicit length 1!
18955 ArraySizes.push_back(llvm::APSInt::get(1));
18956 } else {
18957 Expr::EvalResult Result;
18958 if (!Length->EvaluateAsInt(Result, Context))
18959 return false;
18960
18961 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18962 if (ConstantLengthValue.getSExtValue() != 1)
18963 return false;
18964
18965 ArraySizes.push_back(ConstantLengthValue);
18966 }
18967 Base = TempOASE->getBase()->IgnoreParenImpCasts();
18968 }
18969
18970 // If we have a single element, we don't need to add the implicit lengths.
18971 if (!SingleElement) {
18972 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
18973 // Has implicit length 1!
18974 ArraySizes.push_back(llvm::APSInt::get(1));
18975 Base = TempASE->getBase()->IgnoreParenImpCasts();
18976 }
18977 }
18978
18979 // This array section can be privatized as a single value or as a constant
18980 // sized array.
18981 return true;
18982}
18983
18984static BinaryOperatorKind
18985getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
18986 if (BOK == BO_Add)
18987 return BO_AddAssign;
18988 if (BOK == BO_Mul)
18989 return BO_MulAssign;
18990 if (BOK == BO_And)
18991 return BO_AndAssign;
18992 if (BOK == BO_Or)
18993 return BO_OrAssign;
18994 if (BOK == BO_Xor)
18995 return BO_XorAssign;
18996 return BOK;
18997}
18998
18999static bool actOnOMPReductionKindClause(
19000 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19001 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19002 SourceLocation ColonLoc, SourceLocation EndLoc,
19003 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19004 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19005 DeclarationName DN = ReductionId.getName();
19006 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19007 BinaryOperatorKind BOK = BO_Comma;
19008
19009 ASTContext &Context = S.Context;
19010 // OpenMP [2.14.3.6, reduction clause]
19011 // C
19012 // reduction-identifier is either an identifier or one of the following
19013 // operators: +, -, *, &, |, ^, && and ||
19014 // C++
19015 // reduction-identifier is either an id-expression or one of the following
19016 // operators: +, -, *, &, |, ^, && and ||
19017 switch (OOK) {
19018 case OO_Plus:
19019 case OO_Minus:
19020 BOK = BO_Add;
19021 break;
19022 case OO_Star:
19023 BOK = BO_Mul;
19024 break;
19025 case OO_Amp:
19026 BOK = BO_And;
19027 break;
19028 case OO_Pipe:
19029 BOK = BO_Or;
19030 break;
19031 case OO_Caret:
19032 BOK = BO_Xor;
19033 break;
19034 case OO_AmpAmp:
19035 BOK = BO_LAnd;
19036 break;
19037 case OO_PipePipe:
19038 BOK = BO_LOr;
19039 break;
19040 case OO_New:
19041 case OO_Delete:
19042 case OO_Array_New:
19043 case OO_Array_Delete:
19044 case OO_Slash:
19045 case OO_Percent:
19046 case OO_Tilde:
19047 case OO_Exclaim:
19048 case OO_Equal:
19049 case OO_Less:
19050 case OO_Greater:
19051 case OO_LessEqual:
19052 case OO_GreaterEqual:
19053 case OO_PlusEqual:
19054 case OO_MinusEqual:
19055 case OO_StarEqual:
19056 case OO_SlashEqual:
19057 case OO_PercentEqual:
19058 case OO_CaretEqual:
19059 case OO_AmpEqual:
19060 case OO_PipeEqual:
19061 case OO_LessLess:
19062 case OO_GreaterGreater:
19063 case OO_LessLessEqual:
19064 case OO_GreaterGreaterEqual:
19065 case OO_EqualEqual:
19066 case OO_ExclaimEqual:
19067 case OO_Spaceship:
19068 case OO_PlusPlus:
19069 case OO_MinusMinus:
19070 case OO_Comma:
19071 case OO_ArrowStar:
19072 case OO_Arrow:
19073 case OO_Call:
19074 case OO_Subscript:
19075 case OO_Conditional:
19076 case OO_Coawait:
19077 case NUM_OVERLOADED_OPERATORS:
19078 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "clang/lib/Sema/SemaOpenMP.cpp", 19078)
;
19079 case OO_None:
19080 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19081 if (II->isStr("max"))
19082 BOK = BO_GT;
19083 else if (II->isStr("min"))
19084 BOK = BO_LT;
19085 }
19086 break;
19087 }
19088 SourceRange ReductionIdRange;
19089 if (ReductionIdScopeSpec.isValid())
19090 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19091 else
19092 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19093 ReductionIdRange.setEnd(ReductionId.getEndLoc());
19094
19095 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19096 bool FirstIter = true;
19097 for (Expr *RefExpr : VarList) {
19098 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", 19098, __extension__ __PRETTY_FUNCTION__
))
;
19099 // OpenMP [2.1, C/C++]
19100 // A list item is a variable or array section, subject to the restrictions
19101 // specified in Section 2.4 on page 42 and in each of the sections
19102 // describing clauses and directives for which a list appears.
19103 // OpenMP [2.14.3.3, Restrictions, p.1]
19104 // A variable that is part of another variable (as an array or
19105 // structure element) cannot appear in a private clause.
19106 if (!FirstIter && IR != ER)
19107 ++IR;
19108 FirstIter = false;
19109 SourceLocation ELoc;
19110 SourceRange ERange;
19111 Expr *SimpleRefExpr = RefExpr;
19112 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19113 /*AllowArraySection=*/true);
19114 if (Res.second) {
19115 // Try to find 'declare reduction' corresponding construct before using
19116 // builtin/overloaded operators.
19117 QualType Type = Context.DependentTy;
19118 CXXCastPath BasePath;
19119 ExprResult DeclareReductionRef = buildDeclareReductionRef(
19120 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19121 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19122 Expr *ReductionOp = nullptr;
19123 if (S.CurContext->isDependentContext() &&
19124 (DeclareReductionRef.isUnset() ||
19125 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19126 ReductionOp = DeclareReductionRef.get();
19127 // It will be analyzed later.
19128 RD.push(RefExpr, ReductionOp);
19129 }
19130 ValueDecl *D = Res.first;
19131 if (!D)
19132 continue;
19133
19134 Expr *TaskgroupDescriptor = nullptr;
19135 QualType Type;
19136 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19137 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19138 if (ASE) {
19139 Type = ASE->getType().getNonReferenceType();
19140 } else if (OASE) {
19141 QualType BaseType =
19142 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19143 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19144 Type = ATy->getElementType();
19145 else
19146 Type = BaseType->getPointeeType();
19147 Type = Type.getNonReferenceType();
19148 } else {
19149 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19150 }
19151 auto *VD = dyn_cast<VarDecl>(D);
19152
19153 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19154 // A variable that appears in a private clause must not have an incomplete
19155 // type or a reference type.
19156 if (S.RequireCompleteType(ELoc, D->getType(),
19157 diag::err_omp_reduction_incomplete_type))
19158 continue;
19159 // OpenMP [2.14.3.6, reduction clause, Restrictions]
19160 // A list item that appears in a reduction clause must not be
19161 // const-qualified.
19162 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19163 /*AcceptIfMutable*/ false, ASE || OASE))
19164 continue;
19165
19166 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19167 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19168 // If a list-item is a reference type then it must bind to the same object
19169 // for all threads of the team.
19170 if (!ASE && !OASE) {
19171 if (VD) {
19172 VarDecl *VDDef = VD->getDefinition();
19173 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19174 DSARefChecker Check(Stack);
19175 if (Check.Visit(VDDef->getInit())) {
19176 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19177 << getOpenMPClauseName(ClauseKind) << ERange;
19178 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19179 continue;
19180 }
19181 }
19182 }
19183
19184 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19185 // in a Construct]
19186 // Variables with the predetermined data-sharing attributes may not be
19187 // listed in data-sharing attributes clauses, except for the cases
19188 // listed below. For these exceptions only, listing a predetermined
19189 // variable in a data-sharing attribute clause is allowed and overrides
19190 // the variable's predetermined data-sharing attributes.
19191 // OpenMP [2.14.3.6, Restrictions, p.3]
19192 // Any number of reduction clauses can be specified on the directive,
19193 // but a list item can appear only once in the reduction clauses for that
19194 // directive.
19195 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19196 if (DVar.CKind == OMPC_reduction) {
19197 S.Diag(ELoc, diag::err_omp_once_referenced)
19198 << getOpenMPClauseName(ClauseKind);
19199 if (DVar.RefExpr)
19200 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19201 continue;
19202 }
19203 if (DVar.CKind != OMPC_unknown) {
19204 S.Diag(ELoc, diag::err_omp_wrong_dsa)
19205 << getOpenMPClauseName(DVar.CKind)
19206 << getOpenMPClauseName(OMPC_reduction);
19207 reportOriginalDsa(S, Stack, D, DVar);
19208 continue;
19209 }
19210
19211 // OpenMP [2.14.3.6, Restrictions, p.1]
19212 // A list item that appears in a reduction clause of a worksharing
19213 // construct must be shared in the parallel regions to which any of the
19214 // worksharing regions arising from the worksharing construct bind.
19215 if (isOpenMPWorksharingDirective(CurrDir) &&
19216 !isOpenMPParallelDirective(CurrDir) &&
19217 !isOpenMPTeamsDirective(CurrDir)) {
19218 DVar = Stack->getImplicitDSA(D, true);
19219 if (DVar.CKind != OMPC_shared) {
19220 S.Diag(ELoc, diag::err_omp_required_access)
19221 << getOpenMPClauseName(OMPC_reduction)
19222 << getOpenMPClauseName(OMPC_shared);
19223 reportOriginalDsa(S, Stack, D, DVar);
19224 continue;
19225 }
19226 }
19227 } else {
19228 // Threadprivates cannot be shared between threads, so dignose if the base
19229 // is a threadprivate variable.
19230 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19231 if (DVar.CKind == OMPC_threadprivate) {
19232 S.Diag(ELoc, diag::err_omp_wrong_dsa)
19233 << getOpenMPClauseName(DVar.CKind)
19234 << getOpenMPClauseName(OMPC_reduction);
19235 reportOriginalDsa(S, Stack, D, DVar);
19236 continue;
19237 }
19238 }
19239
19240 // Try to find 'declare reduction' corresponding construct before using
19241 // builtin/overloaded operators.
19242 CXXCastPath BasePath;
19243 ExprResult DeclareReductionRef = buildDeclareReductionRef(
19244 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19245 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19246 if (DeclareReductionRef.isInvalid())
19247 continue;
19248 if (S.CurContext->isDependentContext() &&
19249 (DeclareReductionRef.isUnset() ||
19250 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19251 RD.push(RefExpr, DeclareReductionRef.get());
19252 continue;
19253 }
19254 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19255 // Not allowed reduction identifier is found.
19256 S.Diag(ReductionId.getBeginLoc(),
19257 diag::err_omp_unknown_reduction_identifier)
19258 << Type << ReductionIdRange;
19259 continue;
19260 }
19261
19262 // OpenMP [2.14.3.6, reduction clause, Restrictions]
19263 // The type of a list item that appears in a reduction clause must be valid
19264 // for the reduction-identifier. For a max or min reduction in C, the type
19265 // of the list item must be an allowed arithmetic data type: char, int,
19266 // float, double, or _Bool, possibly modified with long, short, signed, or
19267 // unsigned. For a max or min reduction in C++, the type of the list item
19268 // must be an allowed arithmetic data type: char, wchar_t, int, float,
19269 // double, or bool, possibly modified with long, short, signed, or unsigned.
19270 if (DeclareReductionRef.isUnset()) {
19271 if ((BOK == BO_GT || BOK == BO_LT) &&
19272 !(Type->isScalarType() ||
19273 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19274 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19275 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19276 if (!ASE && !OASE) {
19277 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19278 VarDecl::DeclarationOnly;
19279 S.Diag(D->getLocation(),
19280 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19281 << D;
19282 }
19283 continue;
19284 }
19285 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19286 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19287 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19288 << getOpenMPClauseName(ClauseKind);
19289 if (!ASE && !OASE) {
19290 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19291 VarDecl::DeclarationOnly;
19292 S.Diag(D->getLocation(),
19293 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19294 << D;
19295 }
19296 continue;
19297 }
19298 }
19299
19300 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19301 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19302 D->hasAttrs() ? &D->getAttrs() : nullptr);
19303 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19304 D->hasAttrs() ? &D->getAttrs() : nullptr);
19305 QualType PrivateTy = Type;
19306
19307 // Try if we can determine constant lengths for all array sections and avoid
19308 // the VLA.
19309 bool ConstantLengthOASE = false;
19310 if (OASE) {
19311 bool SingleElement;
19312 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19313 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19314 Context, OASE, SingleElement, ArraySizes);
19315
19316 // If we don't have a single element, we must emit a constant array type.
19317 if (ConstantLengthOASE && !SingleElement) {
19318 for (llvm::APSInt &Size : ArraySizes)
19319 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19320 ArrayType::Normal,
19321 /*IndexTypeQuals=*/0);
19322 }
19323 }
19324
19325 if ((OASE && !ConstantLengthOASE) ||
19326 (!OASE && !ASE &&
19327 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19328 if (!Context.getTargetInfo().isVLASupported()) {
19329 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19330 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19331 S.Diag(ELoc, diag::note_vla_unsupported);
19332 continue;
19333 } else {
19334 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19335 S.targetDiag(ELoc, diag::note_vla_unsupported);
19336 }
19337 }
19338 // For arrays/array sections only:
19339 // Create pseudo array type for private copy. The size for this array will
19340 // be generated during codegen.
19341 // For array subscripts or single variables Private Ty is the same as Type
19342 // (type of the variable or single array element).
19343 PrivateTy = Context.getVariableArrayType(
19344 Type,
19345 new (Context)
19346 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19347 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
19348 } else if (!ASE && !OASE &&
19349 Context.getAsArrayType(D->getType().getNonReferenceType())) {
19350 PrivateTy = D->getType().getNonReferenceType();
19351 }
19352 // Private copy.
19353 VarDecl *PrivateVD =
19354 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19355 D->hasAttrs() ? &D->getAttrs() : nullptr,
19356 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19357 // Add initializer for private variable.
19358 Expr *Init = nullptr;
19359 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19360 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19361 if (DeclareReductionRef.isUsable()) {
19362 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19363 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19364 if (DRD->getInitializer()) {
19365 Init = DRDRef;
19366 RHSVD->setInit(DRDRef);
19367 RHSVD->setInitStyle(VarDecl::CallInit);
19368 }
19369 } else {
19370 switch (BOK) {
19371 case BO_Add:
19372 case BO_Xor:
19373 case BO_Or:
19374 case BO_LOr:
19375 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19376 if (Type->isScalarType() || Type->isAnyComplexType())
19377 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19378 break;
19379 case BO_Mul:
19380 case BO_LAnd:
19381 if (Type->isScalarType() || Type->isAnyComplexType()) {
19382 // '*' and '&&' reduction ops - initializer is '1'.
19383 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19384 }
19385 break;
19386 case BO_And: {
19387 // '&' reduction op - initializer is '~0'.
19388 QualType OrigType = Type;
19389 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19390 Type = ComplexTy->getElementType();
19391 if (Type->isRealFloatingType()) {
19392 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19393 Context.getFloatTypeSemantics(Type));
19394 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19395 Type, ELoc);
19396 } else if (Type->isScalarType()) {
19397 uint64_t Size = Context.getTypeSize(Type);
19398 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19399 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19400 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19401 }
19402 if (Init && OrigType->isAnyComplexType()) {
19403 // Init = 0xFFFF + 0xFFFFi;
19404 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19405 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19406 }
19407 Type = OrigType;
19408 break;
19409 }
19410 case BO_LT:
19411 case BO_GT: {
19412 // 'min' reduction op - initializer is 'Largest representable number in
19413 // the reduction list item type'.
19414 // 'max' reduction op - initializer is 'Least representable number in
19415 // the reduction list item type'.
19416 if (Type->isIntegerType() || Type->isPointerType()) {
19417 bool IsSigned = Type->hasSignedIntegerRepresentation();
19418 uint64_t Size = Context.getTypeSize(Type);
19419 QualType IntTy =
19420 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19421 llvm::APInt InitValue =
19422 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19423 : llvm::APInt::getMinValue(Size)
19424 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19425 : llvm::APInt::getMaxValue(Size);
19426 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19427 if (Type->isPointerType()) {
19428 // Cast to pointer type.
19429 ExprResult CastExpr = S.BuildCStyleCastExpr(
19430 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19431 if (CastExpr.isInvalid())
19432 continue;
19433 Init = CastExpr.get();
19434 }
19435 } else if (Type->isRealFloatingType()) {
19436 llvm::APFloat InitValue = llvm::APFloat::getLargest(
19437 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19438 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19439 Type, ELoc);
19440 }
19441 break;
19442 }
19443 case BO_PtrMemD:
19444 case BO_PtrMemI:
19445 case BO_MulAssign:
19446 case BO_Div:
19447 case BO_Rem:
19448 case BO_Sub:
19449 case BO_Shl:
19450 case BO_Shr:
19451 case BO_LE:
19452 case BO_GE:
19453 case BO_EQ:
19454 case BO_NE:
19455 case BO_Cmp:
19456 case BO_AndAssign:
19457 case BO_XorAssign:
19458 case BO_OrAssign:
19459 case BO_Assign:
19460 case BO_AddAssign:
19461 case BO_SubAssign:
19462 case BO_DivAssign:
19463 case BO_RemAssign:
19464 case BO_ShlAssign:
19465 case BO_ShrAssign:
19466 case BO_Comma:
19467 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "clang/lib/Sema/SemaOpenMP.cpp", 19467)
;
19468 }
19469 }
19470 if (Init && DeclareReductionRef.isUnset()) {
19471 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19472 // Store initializer for single element in private copy. Will be used
19473 // during codegen.
19474 PrivateVD->setInit(RHSVD->getInit());
19475 PrivateVD->setInitStyle(RHSVD->getInitStyle());
19476 } else if (!Init) {
19477 S.ActOnUninitializedDecl(RHSVD);
19478 // Store initializer for single element in private copy. Will be used
19479 // during codegen.
19480 PrivateVD->setInit(RHSVD->getInit());
19481 PrivateVD->setInitStyle(RHSVD->getInitStyle());
19482 }
19483 if (RHSVD->isInvalidDecl())
19484 continue;
19485 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19486 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19487 << Type << ReductionIdRange;
19488 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19489 VarDecl::DeclarationOnly;
19490 S.Diag(D->getLocation(),
19491 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19492 << D;
19493 continue;
19494 }
19495 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19496 ExprResult ReductionOp;
19497 if (DeclareReductionRef.isUsable()) {
19498 QualType RedTy = DeclareReductionRef.get()->getType();
19499 QualType PtrRedTy = Context.getPointerType(RedTy);
19500 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19501 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19502 if (!BasePath.empty()) {
19503 LHS = S.DefaultLvalueConversion(LHS.get());
19504 RHS = S.DefaultLvalueConversion(RHS.get());
19505 LHS = ImplicitCastExpr::Create(
19506 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19507 LHS.get()->getValueKind(), FPOptionsOverride());
19508 RHS = ImplicitCastExpr::Create(
19509 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19510 RHS.get()->getValueKind(), FPOptionsOverride());
19511 }
19512 FunctionProtoType::ExtProtoInfo EPI;
19513 QualType Params[] = {PtrRedTy, PtrRedTy};
19514 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19515 auto *OVE = new (Context) OpaqueValueExpr(
19516 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19517 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19518 Expr *Args[] = {LHS.get(), RHS.get()};
19519 ReductionOp =
19520 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19521 S.CurFPFeatureOverrides());
19522 } else {
19523 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19524 if (Type->isRecordType() && CombBOK != BOK) {
19525 Sema::TentativeAnalysisScope Trap(S);
19526 ReductionOp =
19527 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19528 CombBOK, LHSDRE, RHSDRE);
19529 }
19530 if (!ReductionOp.isUsable()) {
19531 ReductionOp =
19532 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19533 LHSDRE, RHSDRE);
19534 if (ReductionOp.isUsable()) {
19535 if (BOK != BO_LT && BOK != BO_GT) {
19536 ReductionOp =
19537 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19538 BO_Assign, LHSDRE, ReductionOp.get());
19539 } else {
19540 auto *ConditionalOp = new (Context)
19541 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19542 RHSDRE, Type, VK_LValue, OK_Ordinary);
19543 ReductionOp =
19544 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19545 BO_Assign, LHSDRE, ConditionalOp);
19546 }
19547 }
19548 }
19549 if (ReductionOp.isUsable())
19550 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19551 /*DiscardedValue*/ false);
19552 if (!ReductionOp.isUsable())
19553 continue;
19554 }
19555
19556 // Add copy operations for inscan reductions.
19557 // LHS = RHS;
19558 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19559 if (ClauseKind == OMPC_reduction &&
19560 RD.RedModifier == OMPC_REDUCTION_inscan) {
19561 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19562 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19563 RHS.get());
19564 if (!CopyOpRes.isUsable())
19565 continue;
19566 CopyOpRes =
19567 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19568 if (!CopyOpRes.isUsable())
19569 continue;
19570 // For simd directive and simd-based directives in simd mode no need to
19571 // construct temp array, need just a single temp element.
19572 if (Stack->getCurrentDirective() == OMPD_simd ||
19573 (S.getLangOpts().OpenMPSimd &&
19574 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
19575 VarDecl *TempArrayVD =
19576 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19577 D->hasAttrs() ? &D->getAttrs() : nullptr);
19578 // Add a constructor to the temp decl.
19579 S.ActOnUninitializedDecl(TempArrayVD);
19580 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19581 } else {
19582 // Build temp array for prefix sum.
19583 auto *Dim = new (S.Context)
19584 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19585 QualType ArrayTy =
19586 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
19587 /*IndexTypeQuals=*/0, {ELoc, ELoc});
19588 VarDecl *TempArrayVD =
19589 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19590 D->hasAttrs() ? &D->getAttrs() : nullptr);
19591 // Add a constructor to the temp decl.
19592 S.ActOnUninitializedDecl(TempArrayVD);
19593 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19594 TempArrayElem =
19595 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19596 auto *Idx = new (S.Context)
19597 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19598 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19599 ELoc, Idx, ELoc);
19600 }
19601 }
19602
19603 // OpenMP [2.15.4.6, Restrictions, p.2]
19604 // A list item that appears in an in_reduction clause of a task construct
19605 // must appear in a task_reduction clause of a construct associated with a
19606 // taskgroup region that includes the participating task in its taskgroup
19607 // set. The construct associated with the innermost region that meets this
19608 // condition must specify the same reduction-identifier as the in_reduction
19609 // clause.
19610 if (ClauseKind == OMPC_in_reduction) {
19611 SourceRange ParentSR;
19612 BinaryOperatorKind ParentBOK;
19613 const Expr *ParentReductionOp = nullptr;
19614 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19615 DSAStackTy::DSAVarData ParentBOKDSA =
19616 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19617 ParentBOKTD);
19618 DSAStackTy::DSAVarData ParentReductionOpDSA =
19619 Stack->getTopMostTaskgroupReductionData(
19620 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19621 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19622 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19623 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
19624 (DeclareReductionRef.isUsable() && IsParentBOK) ||
19625 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19626 bool EmitError = true;
19627 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
19628 llvm::FoldingSetNodeID RedId, ParentRedId;
19629 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19630 DeclareReductionRef.get()->Profile(RedId, Context,
19631 /*Canonical=*/true);
19632 EmitError = RedId != ParentRedId;
19633 }
19634 if (EmitError) {
19635 S.Diag(ReductionId.getBeginLoc(),
19636 diag::err_omp_reduction_identifier_mismatch)
19637 << ReductionIdRange << RefExpr->getSourceRange();
19638 S.Diag(ParentSR.getBegin(),
19639 diag::note_omp_previous_reduction_identifier)
19640 << ParentSR
19641 << (IsParentBOK ? ParentBOKDSA.RefExpr
19642 : ParentReductionOpDSA.RefExpr)
19643 ->getSourceRange();
19644 continue;
19645 }
19646 }
19647 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19648 }
19649
19650 DeclRefExpr *Ref = nullptr;
19651 Expr *VarsExpr = RefExpr->IgnoreParens();
19652 if (!VD && !S.CurContext->isDependentContext()) {
19653 if (ASE || OASE) {
19654 TransformExprToCaptures RebuildToCapture(S, D);
19655 VarsExpr =
19656 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19657 Ref = RebuildToCapture.getCapturedExpr();
19658 } else {
19659 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
19660 }
19661 if (!S.isOpenMPCapturedDecl(D)) {
19662 RD.ExprCaptures.emplace_back(Ref->getDecl());
19663 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19664 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
19665 if (!RefRes.isUsable())
19666 continue;
19667 ExprResult PostUpdateRes =
19668 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19669 RefRes.get());
19670 if (!PostUpdateRes.isUsable())
19671 continue;
19672 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
19673 Stack->getCurrentDirective() == OMPD_taskgroup) {
19674 S.Diag(RefExpr->getExprLoc(),
19675 diag::err_omp_reduction_non_addressable_expression)
19676 << RefExpr->getSourceRange();
19677 continue;
19678 }
19679 RD.ExprPostUpdates.emplace_back(
19680 S.IgnoredValueConversions(PostUpdateRes.get()).get());
19681 }
19682 }
19683 }
19684 // All reduction items are still marked as reduction (to do not increase
19685 // code base size).
19686 unsigned Modifier = RD.RedModifier;
19687 // Consider task_reductions as reductions with task modifier. Required for
19688 // correct analysis of in_reduction clauses.
19689 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19690 Modifier = OMPC_REDUCTION_task;
19691 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19692 ASE || OASE);
19693 if (Modifier == OMPC_REDUCTION_task &&
19694 (CurrDir == OMPD_taskgroup ||
19695 ((isOpenMPParallelDirective(CurrDir) ||
19696 isOpenMPWorksharingDirective(CurrDir)) &&
19697 !isOpenMPSimdDirective(CurrDir)))) {
19698 if (DeclareReductionRef.isUsable())
19699 Stack->addTaskgroupReductionData(D, ReductionIdRange,
19700 DeclareReductionRef.get());
19701 else
19702 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19703 }
19704 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
19705 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19706 TempArrayElem.get());
19707 }
19708 return RD.Vars.empty();
19709}
19710
19711OMPClause *Sema::ActOnOpenMPReductionClause(
19712 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
19713 SourceLocation StartLoc, SourceLocation LParenLoc,
19714 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
19715 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19716 ArrayRef<Expr *> UnresolvedReductions) {
19717 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
19718 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19719 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
19720 /*Last=*/OMPC_REDUCTION_unknown)
19721 << getOpenMPClauseName(OMPC_reduction);
19722 return nullptr;
19723 }
19724 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19725 // A reduction clause with the inscan reduction-modifier may only appear on a
19726 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19727 // construct, a parallel worksharing-loop construct or a parallel
19728 // worksharing-loop SIMD construct.
19729 if (Modifier == OMPC_REDUCTION_inscan &&
19730 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
19731 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
19732 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
19733 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
19734 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
19735 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19736 return nullptr;
19737 }
19738
19739 ReductionData RD(VarList.size(), Modifier);
19740 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
19741 StartLoc, LParenLoc, ColonLoc, EndLoc,
19742 ReductionIdScopeSpec, ReductionId,
19743 UnresolvedReductions, RD))
19744 return nullptr;
19745
19746 return OMPReductionClause::Create(
19747 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
19748 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19749 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19750 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19751 buildPreInits(Context, RD.ExprCaptures),
19752 buildPostUpdate(*this, RD.ExprPostUpdates));
19753}
19754
19755OMPClause *Sema::ActOnOpenMPTaskReductionClause(
19756 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19757 SourceLocation ColonLoc, SourceLocation EndLoc,
19758 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19759 ArrayRef<Expr *> UnresolvedReductions) {
19760 ReductionData RD(VarList.size());
19761 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
19762 StartLoc, LParenLoc, ColonLoc, EndLoc,
19763 ReductionIdScopeSpec, ReductionId,
19764 UnresolvedReductions, RD))
19765 return nullptr;
19766
19767 return OMPTaskReductionClause::Create(
19768 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19769 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19770 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19771 buildPreInits(Context, RD.ExprCaptures),
19772 buildPostUpdate(*this, RD.ExprPostUpdates));
19773}
19774
19775OMPClause *Sema::ActOnOpenMPInReductionClause(
19776 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19777 SourceLocation ColonLoc, SourceLocation EndLoc,
19778 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19779 ArrayRef<Expr *> UnresolvedReductions) {
19780 ReductionData RD(VarList.size());
19781 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
19782 StartLoc, LParenLoc, ColonLoc, EndLoc,
19783 ReductionIdScopeSpec, ReductionId,
19784 UnresolvedReductions, RD))
19785 return nullptr;
19786
19787 return OMPInReductionClause::Create(
19788 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19789 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19790 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19791 buildPreInits(Context, RD.ExprCaptures),
19792 buildPostUpdate(*this, RD.ExprPostUpdates));
19793}
19794
19795bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
19796 SourceLocation LinLoc) {
19797 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19798 LinKind == OMPC_LINEAR_unknown) {
19799 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19800 return true;
19801 }
19802 return false;
19803}
19804
19805bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
19806 OpenMPLinearClauseKind LinKind, QualType Type,
19807 bool IsDeclareSimd) {
19808 const auto *VD = dyn_cast_or_null<VarDecl>(D);
19809 // A variable must not have an incomplete type or a reference type.
19810 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19811 return true;
19812 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19813 !Type->isReferenceType()) {
19814 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19815 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19816 return true;
19817 }
19818 Type = Type.getNonReferenceType();
19819
19820 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19821 // A variable that is privatized must not have a const-qualified type
19822 // unless it is of class type with a mutable member. This restriction does
19823 // not apply to the firstprivate clause, nor to the linear clause on
19824 // declarative directives (like declare simd).
19825 if (!IsDeclareSimd &&
19826 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19827 return true;
19828
19829 // A list item must be of integral or pointer type.
19830 Type = Type.getUnqualifiedType().getCanonicalType();
19831 const auto *Ty = Type.getTypePtrOrNull();
19832 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19833 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
19834 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19835 if (D) {
19836 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19837 VarDecl::DeclarationOnly;
19838 Diag(D->getLocation(),
19839 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19840 << D;
19841 }
19842 return true;
19843 }
19844 return false;
19845}
19846
19847OMPClause *Sema::ActOnOpenMPLinearClause(
19848 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19849 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19850 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19851 SmallVector<Expr *, 8> Vars;
19852 SmallVector<Expr *, 8> Privates;
19853 SmallVector<Expr *, 8> Inits;
19854 SmallVector<Decl *, 4> ExprCaptures;
19855 SmallVector<Expr *, 4> ExprPostUpdates;
19856 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19857 LinKind = OMPC_LINEAR_val;
19858 for (Expr *RefExpr : VarList) {
19859 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", 19859, __extension__ __PRETTY_FUNCTION__
))
;
19860 SourceLocation ELoc;
19861 SourceRange ERange;
19862 Expr *SimpleRefExpr = RefExpr;
19863 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19864 if (Res.second) {
19865 // It will be analyzed later.
19866 Vars.push_back(RefExpr);
19867 Privates.push_back(nullptr);
19868 Inits.push_back(nullptr);
19869 }
19870 ValueDecl *D = Res.first;
19871 if (!D)
19872 continue;
19873
19874 QualType Type = D->getType();
19875 auto *VD = dyn_cast<VarDecl>(D);
19876
19877 // OpenMP [2.14.3.7, linear clause]
19878 // A list-item cannot appear in more than one linear clause.
19879 // A list-item that appears in a linear clause cannot appear in any
19880 // other data-sharing attribute clause.
19881 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
19882 if (DVar.RefExpr) {
19883 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19884 << getOpenMPClauseName(OMPC_linear);
19885 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
19886 continue;
19887 }
19888
19889 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19890 continue;
19891 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19892
19893 // Build private copy of original var.
19894 VarDecl *Private =
19895 buildVarDecl(*this, ELoc, Type, D->getName(),
19896 D->hasAttrs() ? &D->getAttrs() : nullptr,
19897 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19898 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
19899 // Build var to save initial value.
19900 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
19901 Expr *InitExpr;
19902 DeclRefExpr *Ref = nullptr;
19903 if (!VD && !CurContext->isDependentContext()) {
19904 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
19905 if (!isOpenMPCapturedDecl(D)) {
19906 ExprCaptures.push_back(Ref->getDecl());
19907 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19908 ExprResult RefRes = DefaultLvalueConversion(Ref);
19909 if (!RefRes.isUsable())
19910 continue;
19911 ExprResult PostUpdateRes =
19912 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
19913 SimpleRefExpr, RefRes.get());
19914 if (!PostUpdateRes.isUsable())
19915 continue;
19916 ExprPostUpdates.push_back(
19917 IgnoredValueConversions(PostUpdateRes.get()).get());
19918 }
19919 }
19920 }
19921 if (LinKind == OMPC_LINEAR_uval)
19922 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19923 else
19924 InitExpr = VD ? SimpleRefExpr : Ref;
19925 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
19926 /*DirectInit=*/false);
19927 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
19928
19929 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19930 Vars.push_back((VD || CurContext->isDependentContext())
19931 ? RefExpr->IgnoreParens()
19932 : Ref);
19933 Privates.push_back(PrivateRef);
19934 Inits.push_back(InitRef);
19935 }
19936
19937 if (Vars.empty())
19938 return nullptr;
19939
19940 Expr *StepExpr = Step;
19941 Expr *CalcStepExpr = nullptr;
19942 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
19943 !Step->isInstantiationDependent() &&
19944 !Step->containsUnexpandedParameterPack()) {
19945 SourceLocation StepLoc = Step->getBeginLoc();
19946 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
19947 if (Val.isInvalid())
19948 return nullptr;
19949 StepExpr = Val.get();
19950
19951 // Build var to save the step value.
19952 VarDecl *SaveVar =
19953 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
19954 ExprResult SaveRef =
19955 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
19956 ExprResult CalcStep =
19957 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
19958 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
19959
19960 // Warn about zero linear step (it would be probably better specified as
19961 // making corresponding variables 'const').
19962 if (Optional<llvm::APSInt> Result =
19963 StepExpr->getIntegerConstantExpr(Context)) {
19964 if (!Result->isNegative() && !Result->isStrictlyPositive())
19965 Diag(StepLoc, diag::warn_omp_linear_step_zero)
19966 << Vars[0] << (Vars.size() > 1);
19967 } else if (CalcStep.isUsable()) {
19968 // Calculate the step beforehand instead of doing this on each iteration.
19969 // (This is not used if the number of iterations may be kfold-ed).
19970 CalcStepExpr = CalcStep.get();
19971 }
19972 }
19973
19974 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
19975 ColonLoc, EndLoc, Vars, Privates, Inits,
19976 StepExpr, CalcStepExpr,
19977 buildPreInits(Context, ExprCaptures),
19978 buildPostUpdate(*this, ExprPostUpdates));
19979}
19980
19981static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
19982 Expr *NumIterations, Sema &SemaRef,
19983 Scope *S, DSAStackTy *Stack) {
19984 // Walk the vars and build update/final expressions for the CodeGen.
19985 SmallVector<Expr *, 8> Updates;
19986 SmallVector<Expr *, 8> Finals;
19987 SmallVector<Expr *, 8> UsedExprs;
19988 Expr *Step = Clause.getStep();
19989 Expr *CalcStep = Clause.getCalcStep();
19990 // OpenMP [2.14.3.7, linear clause]
19991 // If linear-step is not specified it is assumed to be 1.
19992 if (!Step)
19993 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
19994 else if (CalcStep)
19995 Step = cast<BinaryOperator>(CalcStep)->getLHS();
19996 bool HasErrors = false;
19997 auto CurInit = Clause.inits().begin();
19998 auto CurPrivate = Clause.privates().begin();
19999 OpenMPLinearClauseKind LinKind = Clause.getModifier();
20000 for (Expr *RefExpr : Clause.varlists()) {
20001 SourceLocation ELoc;
20002 SourceRange ERange;
20003 Expr *SimpleRefExpr = RefExpr;
20004 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20005 ValueDecl *D = Res.first;
20006 if (Res.second || !D) {
20007 Updates.push_back(nullptr);
20008 Finals.push_back(nullptr);
20009 HasErrors = true;
20010 continue;
20011 }
20012 auto &&Info = Stack->isLoopControlVariable(D);
20013 // OpenMP [2.15.11, distribute simd Construct]
20014 // A list item may not appear in a linear clause, unless it is the loop
20015 // iteration variable.
20016 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20017 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20018 SemaRef.Diag(ELoc,
20019 diag::err_omp_linear_distribute_var_non_loop_iteration);
20020 Updates.push_back(nullptr);
20021 Finals.push_back(nullptr);
20022 HasErrors = true;
20023 continue;
20024 }
20025 Expr *InitExpr = *CurInit;
20026
20027 // Build privatized reference to the current linear var.
20028 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20029 Expr *CapturedRef;
20030 if (LinKind == OMPC_LINEAR_uval)
20031 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20032 else
20033 CapturedRef =
20034 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20035 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20036 /*RefersToCapture=*/true);
20037
20038 // Build update: Var = InitExpr + IV * Step
20039 ExprResult Update;
20040 if (!Info.first)
20041 Update = buildCounterUpdate(
20042 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20043 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20044 else
20045 Update = *CurPrivate;
20046 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20047 /*DiscardedValue*/ false);
20048
20049 // Build final: Var = PrivCopy;
20050 ExprResult Final;
20051 if (!Info.first)
20052 Final = SemaRef.BuildBinOp(
20053 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20054 SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20055 else
20056 Final = *CurPrivate;
20057 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20058 /*DiscardedValue*/ false);
20059
20060 if (!Update.isUsable() || !Final.isUsable()) {
20061 Updates.push_back(nullptr);
20062 Finals.push_back(nullptr);
20063 UsedExprs.push_back(nullptr);
20064 HasErrors = true;
20065 } else {
20066 Updates.push_back(Update.get());
20067 Finals.push_back(Final.get());
20068 if (!Info.first)
20069 UsedExprs.push_back(SimpleRefExpr);
20070 }
20071 ++CurInit;
20072 ++CurPrivate;
20073 }
20074 if (Expr *S = Clause.getStep())
20075 UsedExprs.push_back(S);
20076 // Fill the remaining part with the nullptr.
20077 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20078 Clause.setUpdates(Updates);
20079 Clause.setFinals(Finals);
20080 Clause.setUsedExprs(UsedExprs);
20081 return HasErrors;
20082}
20083
20084OMPClause *Sema::ActOnOpenMPAlignedClause(
20085 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20086 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20087 SmallVector<Expr *, 8> Vars;
20088 for (Expr *RefExpr : VarList) {
20089 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", 20089, __extension__ __PRETTY_FUNCTION__
))
;
20090 SourceLocation ELoc;
20091 SourceRange ERange;
20092 Expr *SimpleRefExpr = RefExpr;
20093 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20094 if (Res.second) {
20095 // It will be analyzed later.
20096 Vars.push_back(RefExpr);
20097 }
20098 ValueDecl *D = Res.first;
20099 if (!D)
20100 continue;
20101
20102 QualType QType = D->getType();
20103 auto *VD = dyn_cast<VarDecl>(D);
20104
20105 // OpenMP [2.8.1, simd construct, Restrictions]
20106 // The type of list items appearing in the aligned clause must be
20107 // array, pointer, reference to array, or reference to pointer.
20108 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20109 const Type *Ty = QType.getTypePtrOrNull();
20110 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20111 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20112 << QType << getLangOpts().CPlusPlus << ERange;
20113 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20114 VarDecl::DeclarationOnly;
20115 Diag(D->getLocation(),
20116 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20117 << D;
20118 continue;
20119 }
20120
20121 // OpenMP [2.8.1, simd construct, Restrictions]
20122 // A list-item cannot appear in more than one aligned clause.
20123 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
20124 Diag(ELoc, diag::err_omp_used_in_clause_twice)
20125 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20126 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20127 << getOpenMPClauseName(OMPC_aligned);
20128 continue;
20129 }
20130
20131 DeclRefExpr *Ref = nullptr;
20132 if (!VD && isOpenMPCapturedDecl(D))
20133 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20134 Vars.push_back(DefaultFunctionArrayConversion(
20135 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20136 .get());
20137 }
20138
20139 // OpenMP [2.8.1, simd construct, Description]
20140 // The parameter of the aligned clause, alignment, must be a constant
20141 // positive integer expression.
20142 // If no optional parameter is specified, implementation-defined default
20143 // alignments for SIMD instructions on the target platforms are assumed.
20144 if (Alignment != nullptr) {
20145 ExprResult AlignResult =
20146 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20147 if (AlignResult.isInvalid())
20148 return nullptr;
20149 Alignment = AlignResult.get();
20150 }
20151 if (Vars.empty())
20152 return nullptr;
20153
20154 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20155 EndLoc, Vars, Alignment);
20156}
20157
20158OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20159 SourceLocation StartLoc,
20160 SourceLocation LParenLoc,
20161 SourceLocation EndLoc) {
20162 SmallVector<Expr *, 8> Vars;
20163 SmallVector<Expr *, 8> SrcExprs;
20164 SmallVector<Expr *, 8> DstExprs;
20165 SmallVector<Expr *, 8> AssignmentOps;
20166 for (Expr *RefExpr : VarList) {
20167 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", 20167, __extension__ __PRETTY_FUNCTION__
))
;
20168 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20169 // It will be analyzed later.
20170 Vars.push_back(RefExpr);
20171 SrcExprs.push_back(nullptr);
20172 DstExprs.push_back(nullptr);
20173 AssignmentOps.push_back(nullptr);
20174 continue;
20175 }
20176
20177 SourceLocation ELoc = RefExpr->getExprLoc();
20178 // OpenMP [2.1, C/C++]
20179 // A list item is a variable name.
20180 // OpenMP [2.14.4.1, Restrictions, p.1]
20181 // A list item that appears in a copyin clause must be threadprivate.
20182 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20183 if (!DE || !isa<VarDecl>(DE->getDecl())) {
20184 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20185 << 0 << RefExpr->getSourceRange();
20186 continue;
20187 }
20188
20189 Decl *D = DE->getDecl();
20190 auto *VD = cast<VarDecl>(D);
20191
20192 QualType Type = VD->getType();
20193 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
20194 // It will be analyzed later.
20195 Vars.push_back(DE);
20196 SrcExprs.push_back(nullptr);
20197 DstExprs.push_back(nullptr);
20198 AssignmentOps.push_back(nullptr);
20199 continue;
20200 }
20201
20202 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20203 // A list item that appears in a copyin clause must be threadprivate.
20204 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
20205 Diag(ELoc, diag::err_omp_required_access)
20206 << getOpenMPClauseName(OMPC_copyin)
20207 << getOpenMPDirectiveName(OMPD_threadprivate);
20208 continue;
20209 }
20210
20211 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20212 // A variable of class type (or array thereof) that appears in a
20213 // copyin clause requires an accessible, unambiguous copy assignment
20214 // operator for the class type.
20215 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20216 VarDecl *SrcVD =
20217 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20218 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20219 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20220 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20221 VarDecl *DstVD =
20222 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20223 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20224 DeclRefExpr *PseudoDstExpr =
20225 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20226 // For arrays generate assignment operation for single element and replace
20227 // it by the original array element in CodeGen.
20228 ExprResult AssignmentOp =
20229 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20230 PseudoSrcExpr);
20231 if (AssignmentOp.isInvalid())
20232 continue;
20233 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20234 /*DiscardedValue*/ false);
20235 if (AssignmentOp.isInvalid())
20236 continue;
20237
20238 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
20239 Vars.push_back(DE);
20240 SrcExprs.push_back(PseudoSrcExpr);
20241 DstExprs.push_back(PseudoDstExpr);
20242 AssignmentOps.push_back(AssignmentOp.get());
20243 }
20244
20245 if (Vars.empty())
20246 return nullptr;
20247
20248 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20249 SrcExprs, DstExprs, AssignmentOps);
20250}
20251
20252OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20253 SourceLocation StartLoc,
20254 SourceLocation LParenLoc,
20255 SourceLocation EndLoc) {
20256 SmallVector<Expr *, 8> Vars;
20257 SmallVector<Expr *, 8> SrcExprs;
20258 SmallVector<Expr *, 8> DstExprs;
20259 SmallVector<Expr *, 8> AssignmentOps;
20260 for (Expr *RefExpr : VarList) {
20261 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", 20261, __extension__ __PRETTY_FUNCTION__
))
;
20262 SourceLocation ELoc;
20263 SourceRange ERange;
20264 Expr *SimpleRefExpr = RefExpr;
20265 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20266 if (Res.second) {
20267 // It will be analyzed later.
20268 Vars.push_back(RefExpr);
20269 SrcExprs.push_back(nullptr);
20270 DstExprs.push_back(nullptr);
20271 AssignmentOps.push_back(nullptr);
20272 }
20273 ValueDecl *D = Res.first;
20274 if (!D)
20275 continue;
20276
20277 QualType Type = D->getType();
20278 auto *VD = dyn_cast<VarDecl>(D);
20279
20280 // OpenMP [2.14.4.2, Restrictions, p.2]
20281 // A list item that appears in a copyprivate clause may not appear in a
20282 // private or firstprivate clause on the single construct.
20283 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
20284 DSAStackTy::DSAVarData DVar =
20285 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
20286 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20287 DVar.RefExpr) {
20288 Diag(ELoc, diag::err_omp_wrong_dsa)
20289 << getOpenMPClauseName(DVar.CKind)
20290 << getOpenMPClauseName(OMPC_copyprivate);
20291 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
20292 continue;
20293 }
20294
20295 // OpenMP [2.11.4.2, Restrictions, p.1]
20296 // All list items that appear in a copyprivate clause must be either
20297 // threadprivate or private in the enclosing context.
20298 if (DVar.CKind == OMPC_unknown) {
20299 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
20300 if (DVar.CKind == OMPC_shared) {
20301 Diag(ELoc, diag::err_omp_required_access)
20302 << getOpenMPClauseName(OMPC_copyprivate)
20303 << "threadprivate or private in the enclosing context";
20304 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
20305 continue;
20306 }
20307 }
20308 }
20309
20310 // Variably modified types are not supported.
20311 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20312 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20313 << getOpenMPClauseName(OMPC_copyprivate) << Type
20314 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
20315 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20316 VarDecl::DeclarationOnly;
20317 Diag(D->getLocation(),
20318 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20319 << D;
20320 continue;
20321 }
20322
20323 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20324 // A variable of class type (or array thereof) that appears in a
20325 // copyin clause requires an accessible, unambiguous copy assignment
20326 // operator for the class type.
20327 Type = Context.getBaseElementType(Type.getNonReferenceType())
20328 .getUnqualifiedType();
20329 VarDecl *SrcVD =
20330 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20331 D->hasAttrs() ? &D->getAttrs() : nullptr);
20332 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20333 VarDecl *DstVD =
20334 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20335 D->hasAttrs() ? &D->getAttrs() : nullptr);
20336 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20337 ExprResult AssignmentOp = BuildBinOp(
20338 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20339 if (AssignmentOp.isInvalid())
20340 continue;
20341 AssignmentOp =
20342 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20343 if (AssignmentOp.isInvalid())
20344 continue;
20345
20346 // No need to mark vars as copyprivate, they are already threadprivate or
20347 // implicitly private.
20348 assert(VD || isOpenMPCapturedDecl(D))(static_cast <bool> (VD || isOpenMPCapturedDecl(D)) ? void
(0) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "clang/lib/Sema/SemaOpenMP.cpp"
, 20348, __extension__ __PRETTY_FUNCTION__))
;
20349 Vars.push_back(
20350 VD ? RefExpr->IgnoreParens()
20351 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20352 SrcExprs.push_back(PseudoSrcExpr);
20353 DstExprs.push_back(PseudoDstExpr);
20354 AssignmentOps.push_back(AssignmentOp.get());
20355 }
20356
20357 if (Vars.empty())
20358 return nullptr;
20359
20360 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20361 Vars, SrcExprs, DstExprs, AssignmentOps);
20362}
20363
20364OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20365 SourceLocation StartLoc,
20366 SourceLocation LParenLoc,
20367 SourceLocation EndLoc) {
20368 if (VarList.empty())
20369 return nullptr;
20370
20371 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20372}
20373
20374/// Tries to find omp_depend_t. type.
20375static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20376 bool Diagnose = true) {
20377 QualType OMPDependT = Stack->getOMPDependT();
20378 if (!OMPDependT.isNull())
20379 return true;
20380 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20381 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20382 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20383 if (Diagnose)
20384 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20385 return false;
20386 }
20387 Stack->setOMPDependT(PT.get());
20388 return true;
20389}
20390
20391OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20392 SourceLocation LParenLoc,
20393 SourceLocation EndLoc) {
20394 if (!Depobj)
20395 return nullptr;
20396
20397 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
20398
20399 // OpenMP 5.0, 2.17.10.1 depobj Construct
20400 // depobj is an lvalue expression of type omp_depend_t.
20401 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20402 !Depobj->isInstantiationDependent() &&
20403 !Depobj->containsUnexpandedParameterPack() &&
20404 (OMPDependTFound &&
20405 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
20406 /*CompareUnqualified=*/true))) {
20407 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20408 << 0 << Depobj->getType() << Depobj->getSourceRange();
20409 }
20410
20411 if (!Depobj->isLValue()) {
20412 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20413 << 1 << Depobj->getSourceRange();
20414 }
20415
20416 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20417}
20418
20419OMPClause *
20420Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20421 Expr *DepModifier, ArrayRef<Expr *> VarList,
20422 SourceLocation StartLoc, SourceLocation LParenLoc,
20423 SourceLocation EndLoc) {
20424 OpenMPDependClauseKind DepKind = Data.DepKind;
20425 SourceLocation DepLoc = Data.DepLoc;
20426 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
20427 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20428 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20429 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20430 return nullptr;
20431 }
20432 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_taskwait &&
20433 DepKind == OMPC_DEPEND_mutexinoutset) {
20434 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20435 return nullptr;
20436 }
20437 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
20438 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
20439 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20440 DepKind == OMPC_DEPEND_sink ||
20441 ((LangOpts.OpenMP < 50 ||
20442 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
20443 DepKind == OMPC_DEPEND_depobj))) {
20444 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20445 OMPC_DEPEND_outallmemory,
20446 OMPC_DEPEND_inoutallmemory};
20447 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
20448 Except.push_back(OMPC_DEPEND_depobj);
20449 if (LangOpts.OpenMP < 51)
20450 Except.push_back(OMPC_DEPEND_inoutset);
20451 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
20452 ? "depend modifier(iterator) or "
20453 : "";
20454 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20455 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20456 /*Last=*/OMPC_DEPEND_unknown,
20457 Except)
20458 << getOpenMPClauseName(OMPC_depend);
20459 return nullptr;
20460 }
20461 if (DepModifier &&
20462 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20463 Diag(DepModifier->getExprLoc(),
20464 diag::err_omp_depend_sink_source_with_modifier);
20465 return nullptr;
20466 }
20467 if (DepModifier &&
20468 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
20469 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20470
20471 SmallVector<Expr *, 8> Vars;
20472 DSAStackTy::OperatorOffsetTy OpsOffs;
20473 llvm::APSInt DepCounter(/*BitWidth=*/32);
20474 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20475 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20476 if (const Expr *OrderedCountExpr =
20477 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
20478 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
20479 TotalDepCount.setIsUnsigned(/*Val=*/true);
20480 }
20481 }
20482 for (Expr *RefExpr : VarList) {
20483 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", 20483, __extension__ __PRETTY_FUNCTION__
))
;
20484 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20485 // It will be analyzed later.
20486 Vars.push_back(RefExpr);
20487 continue;
20488 }
20489
20490 SourceLocation ELoc = RefExpr->getExprLoc();
20491 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20492 if (DepKind == OMPC_DEPEND_sink) {
20493 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
20494 DepCounter >= TotalDepCount) {
20495 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20496 continue;
20497 }
20498 ++DepCounter;
20499 // OpenMP [2.13.9, Summary]
20500 // depend(dependence-type : vec), where dependence-type is:
20501 // 'sink' and where vec is the iteration vector, which has the form:
20502 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20503 // where n is the value specified by the ordered clause in the loop
20504 // directive, xi denotes the loop iteration variable of the i-th nested
20505 // loop associated with the loop directive, and di is a constant
20506 // non-negative integer.
20507 if (CurContext->isDependentContext()) {
20508 // It will be analyzed later.
20509 Vars.push_back(RefExpr);
20510 continue;
20511 }
20512 SimpleExpr = SimpleExpr->IgnoreImplicit();
20513 OverloadedOperatorKind OOK = OO_None;
20514 SourceLocation OOLoc;
20515 Expr *LHS = SimpleExpr;
20516 Expr *RHS = nullptr;
20517 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20518 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20519 OOLoc = BO->getOperatorLoc();
20520 LHS = BO->getLHS()->IgnoreParenImpCasts();
20521 RHS = BO->getRHS()->IgnoreParenImpCasts();
20522 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20523 OOK = OCE->getOperator();
20524 OOLoc = OCE->getOperatorLoc();
20525 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20526 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20527 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20528 OOK = MCE->getMethodDecl()
20529 ->getNameInfo()
20530 .getName()
20531 .getCXXOverloadedOperator();
20532 OOLoc = MCE->getCallee()->getExprLoc();
20533 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20534 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20535 }
20536 SourceLocation ELoc;
20537 SourceRange ERange;
20538 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
20539 if (Res.second) {
20540 // It will be analyzed later.
20541 Vars.push_back(RefExpr);
20542 }
20543 ValueDecl *D = Res.first;
20544 if (!D)
20545 continue;
20546
20547 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20548 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20549 continue;
20550 }
20551 if (RHS) {
20552 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
20553 RHS, OMPC_depend, /*StrictlyPositive=*/false);
20554 if (RHSRes.isInvalid())
20555 continue;
20556 }
20557 if (!CurContext->isDependentContext() &&
20558 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
20559 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
20560 const ValueDecl *VD =
20561 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
20562 if (VD)
20563 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20564 << 1 << VD;
20565 else
20566 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
20567 continue;
20568 }
20569 OpsOffs.emplace_back(RHS, OOK);
20570 } else {
20571 bool OMPDependTFound = LangOpts.OpenMP >= 50;
20572 if (OMPDependTFound)
20573 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
20574 DepKind == OMPC_DEPEND_depobj);
20575 if (DepKind == OMPC_DEPEND_depobj) {
20576 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20577 // List items used in depend clauses with the depobj dependence type
20578 // must be expressions of the omp_depend_t type.
20579 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20580 !RefExpr->isInstantiationDependent() &&
20581 !RefExpr->containsUnexpandedParameterPack() &&
20582 (OMPDependTFound &&
20583 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
20584 RefExpr->getType()))) {
20585 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20586 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20587 continue;
20588 }
20589 if (!RefExpr->isLValue()) {
20590 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20591 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20592 continue;
20593 }
20594 } else {
20595 // OpenMP 5.0 [2.17.11, Restrictions]
20596 // List items used in depend clauses cannot be zero-length array
20597 // sections.
20598 QualType ExprTy = RefExpr->getType().getNonReferenceType();
20599 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
20600 if (OASE) {
20601 QualType BaseType =
20602 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
20603 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20604 ExprTy = ATy->getElementType();
20605 else
20606 ExprTy = BaseType->getPointeeType();
20607 ExprTy = ExprTy.getNonReferenceType();
20608 const Expr *Length = OASE->getLength();
20609 Expr::EvalResult Result;
20610 if (Length && !Length->isValueDependent() &&
20611 Length->EvaluateAsInt(Result, Context) &&
20612 Result.Val.getInt().isZero()) {
20613 Diag(ELoc,
20614 diag::err_omp_depend_zero_length_array_section_not_allowed)
20615 << SimpleExpr->getSourceRange();
20616 continue;
20617 }
20618 }
20619
20620 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20621 // List items used in depend clauses with the in, out, inout,
20622 // inoutset, or mutexinoutset dependence types cannot be
20623 // expressions of the omp_depend_t type.
20624 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20625 !RefExpr->isInstantiationDependent() &&
20626 !RefExpr->containsUnexpandedParameterPack() &&
20627 (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20628 (OMPDependTFound &&
20629 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
20630 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20631 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20632 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20633 continue;
20634 }
20635
20636 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20637 if (ASE && !ASE->getBase()->isTypeDependent() &&
20638 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
20639 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20640 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20641 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20642 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20643 continue;
20644 }
20645
20646 ExprResult Res;
20647 {
20648 Sema::TentativeAnalysisScope Trap(*this);
20649 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
20650 RefExpr->IgnoreParenImpCasts());
20651 }
20652 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20653 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20654 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20655 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20656 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20657 continue;
20658 }
20659 }
20660 }
20661 Vars.push_back(RefExpr->IgnoreParenImpCasts());
20662 }
20663
20664 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
20665 TotalDepCount > VarList.size() &&
20666 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
20667 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
20668 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20669 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
20670 }
20671 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20672 DepKind != OMPC_DEPEND_outallmemory &&
20673 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20674 return nullptr;
20675
20676 auto *C = OMPDependClause::Create(
20677 Context, StartLoc, LParenLoc, EndLoc,
20678 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
20679 TotalDepCount.getZExtValue());
20680 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20681 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
20682 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
20683 return C;
20684}
20685
20686OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
20687 Expr *Device, SourceLocation StartLoc,
20688 SourceLocation LParenLoc,
20689 SourceLocation ModifierLoc,
20690 SourceLocation EndLoc) {
20691 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", 20692, __extension__ __PRETTY_FUNCTION__
))
20692 "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", 20692, __extension__ __PRETTY_FUNCTION__
))
;
20693
20694 bool ErrorFound = false;
20695 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
20696 std::string Values =
20697 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
20698 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20699 << Values << getOpenMPClauseName(OMPC_device);
20700 ErrorFound = true;
20701 }
20702
20703 Expr *ValExpr = Device;
20704 Stmt *HelperValStmt = nullptr;
20705
20706 // OpenMP [2.9.1, Restrictions]
20707 // The device expression must evaluate to a non-negative integer value.
20708 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
20709 /*StrictlyPositive=*/false) ||
20710 ErrorFound;
20711 if (ErrorFound)
20712 return nullptr;
20713
20714 // OpenMP 5.0 [2.12.5, Restrictions]
20715 // In case of ancestor device-modifier, a requires directive with
20716 // the reverse_offload clause must be specified.
20717 if (Modifier == OMPC_DEVICE_ancestor) {
20718 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
20719 targetDiag(
20720 StartLoc,
20721 diag::err_omp_device_ancestor_without_requires_reverse_offload);
20722 ErrorFound = true;
20723 }
20724 }
20725
20726 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
20727 OpenMPDirectiveKind CaptureRegion =
20728 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
20729 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20730 ValExpr = MakeFullExpr(ValExpr).get();
20731 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20732 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20733 HelperValStmt = buildPreInits(Context, Captures);
20734 }
20735
20736 return new (Context)
20737 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20738 LParenLoc, ModifierLoc, EndLoc);
20739}
20740
20741static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
20742 DSAStackTy *Stack, QualType QTy,
20743 bool FullCheck = true) {
20744 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
20745 return false;
20746 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
20747 !QTy.isTriviallyCopyableType(SemaRef.Context))
20748 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20749 return true;
20750}
20751
20752/// Return true if it can be proven that the provided array expression
20753/// (array section or array subscript) does NOT specify the whole size of the
20754/// array whose base type is \a BaseQTy.
20755static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
20756 const Expr *E,
20757 QualType BaseQTy) {
20758 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20759
20760 // If this is an array subscript, it refers to the whole size if the size of
20761 // the dimension is constant and equals 1. Also, an array section assumes the
20762 // format of an array subscript if no colon is used.
20763 if (isa<ArraySubscriptExpr>(E) ||
20764 (OASE && OASE->getColonLocFirst().isInvalid())) {
20765 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20766 return ATy->getSize().getSExtValue() != 1;
20767 // Size can't be evaluated statically.
20768 return false;
20769 }
20770
20771 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", 20771, __extension__ __PRETTY_FUNCTION__
))
;
20772 const Expr *LowerBound = OASE->getLowerBound();
20773 const Expr *Length = OASE->getLength();
20774
20775 // If there is a lower bound that does not evaluates to zero, we are not
20776 // covering the whole dimension.
20777 if (LowerBound) {
20778 Expr::EvalResult Result;
20779 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
20780 return false; // Can't get the integer value as a constant.
20781
20782 llvm::APSInt ConstLowerBound = Result.Val.getInt();
20783 if (ConstLowerBound.getSExtValue())
20784 return true;
20785 }
20786
20787 // If we don't have a length we covering the whole dimension.
20788 if (!Length)
20789 return false;
20790
20791 // If the base is a pointer, we don't have a way to get the size of the
20792 // pointee.
20793 if (BaseQTy->isPointerType())
20794 return false;
20795
20796 // We can only check if the length is the same as the size of the dimension
20797 // if we have a constant array.
20798 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20799 if (!CATy)
20800 return false;
20801
20802 Expr::EvalResult Result;
20803 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20804 return false; // Can't get the integer value as a constant.
20805
20806 llvm::APSInt ConstLength = Result.Val.getInt();
20807 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
20808}
20809
20810// Return true if it can be proven that the provided array expression (array
20811// section or array subscript) does NOT specify a single element of the array
20812// whose base type is \a BaseQTy.
20813static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
20814 const Expr *E,
20815 QualType BaseQTy) {
20816 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20817
20818 // An array subscript always refer to a single element. Also, an array section
20819 // assumes the format of an array subscript if no colon is used.
20820 if (isa<ArraySubscriptExpr>(E) ||
20821 (OASE && OASE->getColonLocFirst().isInvalid()))
20822 return false;
20823
20824 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", 20824, __extension__ __PRETTY_FUNCTION__
))
;
20825 const Expr *Length = OASE->getLength();
20826
20827 // If we don't have a length we have to check if the array has unitary size
20828 // for this dimension. Also, we should always expect a length if the base type
20829 // is pointer.
20830 if (!Length) {
20831 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20832 return ATy->getSize().getSExtValue() != 1;
20833 // We cannot assume anything.
20834 return false;
20835 }
20836
20837 // Check if the length evaluates to 1.
20838 Expr::EvalResult Result;
20839 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20840 return false; // Can't get the integer value as a constant.
20841
20842 llvm::APSInt ConstLength = Result.Val.getInt();
20843 return ConstLength.getSExtValue() != 1;
20844}
20845
20846// The base of elements of list in a map clause have to be either:
20847// - a reference to variable or field.
20848// - a member expression.
20849// - an array expression.
20850//
20851// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20852// reference to 'r'.
20853//
20854// If we have:
20855//
20856// struct SS {
20857// Bla S;
20858// foo() {
20859// #pragma omp target map (S.Arr[:12]);
20860// }
20861// }
20862//
20863// We want to retrieve the member expression 'this->S';
20864
20865// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20866// If a list item is an array section, it must specify contiguous storage.
20867//
20868// For this restriction it is sufficient that we make sure only references
20869// to variables or fields and array expressions, and that no array sections
20870// exist except in the rightmost expression (unless they cover the whole
20871// dimension of the array). E.g. these would be invalid:
20872//
20873// r.ArrS[3:5].Arr[6:7]
20874//
20875// r.ArrS[3:5].x
20876//
20877// but these would be valid:
20878// r.ArrS[3].Arr[6:7]
20879//
20880// r.ArrS[3].x
20881namespace {
20882class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20883 Sema &SemaRef;
20884 OpenMPClauseKind CKind = OMPC_unknown;
20885 OpenMPDirectiveKind DKind = OMPD_unknown;
20886 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
20887 bool IsNonContiguous = false;
20888 bool NoDiagnose = false;
20889 const Expr *RelevantExpr = nullptr;
20890 bool AllowUnitySizeArraySection = true;
20891 bool AllowWholeSizeArraySection = true;
20892 bool AllowAnotherPtr = true;
20893 SourceLocation ELoc;
20894 SourceRange ERange;
20895
20896 void emitErrorMsg() {
20897 // If nothing else worked, this is not a valid map clause expression.
20898 if (SemaRef.getLangOpts().OpenMP < 50) {
20899 SemaRef.Diag(ELoc,
20900 diag::err_omp_expected_named_var_member_or_array_expression)
20901 << ERange;
20902 } else {
20903 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20904 << getOpenMPClauseName(CKind) << ERange;
20905 }
20906 }
20907
20908public:
20909 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
20910 if (!isa<VarDecl>(DRE->getDecl())) {
20911 emitErrorMsg();
20912 return false;
20913 }
20914 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", 20914, __extension__ __PRETTY_FUNCTION__
))
;
20915 RelevantExpr = DRE;
20916 // Record the component.
20917 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
20918 return true;
20919 }
20920
20921 bool VisitMemberExpr(MemberExpr *ME) {
20922 Expr *E = ME;
20923 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
20924
20925 if (isa<CXXThisExpr>(BaseE)) {
20926 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", 20926, __extension__ __PRETTY_FUNCTION__
))
;
20927 // We found a base expression: this->Val.
20928 RelevantExpr = ME;
20929 } else {
20930 E = BaseE;
20931 }
20932
20933 if (!isa<FieldDecl>(ME->getMemberDecl())) {
20934 if (!NoDiagnose) {
20935 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20936 << ME->getSourceRange();
20937 return false;
20938 }
20939 if (RelevantExpr)
20940 return false;
20941 return Visit(E);
20942 }
20943
20944 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
20945
20946 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20947 // A bit-field cannot appear in a map clause.
20948 //
20949 if (FD->isBitField()) {
20950 if (!NoDiagnose) {
20951 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20952 << ME->getSourceRange() << getOpenMPClauseName(CKind);
20953 return false;
20954 }
20955 if (RelevantExpr)
20956 return false;
20957 return Visit(E);
20958 }
20959
20960 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20961 // If the type of a list item is a reference to a type T then the type
20962 // will be considered to be T for all purposes of this clause.
20963 QualType CurType = BaseE->getType().getNonReferenceType();
20964
20965 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20966 // A list item cannot be a variable that is a member of a structure with
20967 // a union type.
20968 //
20969 if (CurType->isUnionType()) {
20970 if (!NoDiagnose) {
20971 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20972 << ME->getSourceRange();
20973 return false;
20974 }
20975 return RelevantExpr || Visit(E);
20976 }
20977
20978 // If we got a member expression, we should not expect any array section
20979 // before that:
20980 //
20981 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20982 // If a list item is an element of a structure, only the rightmost symbol
20983 // of the variable reference can be an array section.
20984 //
20985 AllowUnitySizeArraySection = false;
20986 AllowWholeSizeArraySection = false;
20987
20988 // Record the component.
20989 Components.emplace_back(ME, FD, IsNonContiguous);
20990 return RelevantExpr || Visit(E);
20991 }
20992
20993 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
20994 Expr *E = AE->getBase()->IgnoreParenImpCasts();
20995
20996 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
20997 if (!NoDiagnose) {
20998 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20999 << 0 << AE->getSourceRange();
21000 return false;
21001 }
21002 return RelevantExpr || Visit(E);
21003 }
21004
21005 // If we got an array subscript that express the whole dimension we
21006 // can have any array expressions before. If it only expressing part of
21007 // the dimension, we can only have unitary-size array expressions.
21008 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21009 AllowWholeSizeArraySection = false;
21010
21011 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21012 Expr::EvalResult Result;
21013 if (!AE->getIdx()->isValueDependent() &&
21014 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21015 !Result.Val.getInt().isZero()) {
21016 SemaRef.Diag(AE->getIdx()->getExprLoc(),
21017 diag::err_omp_invalid_map_this_expr);
21018 SemaRef.Diag(AE->getIdx()->getExprLoc(),
21019 diag::note_omp_invalid_subscript_on_this_ptr_map);
21020 }
21021 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", 21021, __extension__ __PRETTY_FUNCTION__
))
;
21022 RelevantExpr = TE;
21023 }
21024
21025 // Record the component - we don't have any declaration associated.
21026 Components.emplace_back(AE, nullptr, IsNonContiguous);
21027
21028 return RelevantExpr || Visit(E);
21029 }
21030
21031 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21032 // After OMP 5.0 Array section in reduction clause will be implicitly
21033 // mapped
21034 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", 21035, __extension__ __PRETTY_FUNCTION__
))
21035 "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", 21035, __extension__ __PRETTY_FUNCTION__
))
;
21036 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21037 QualType CurType =
21038 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21039
21040 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21041 // If the type of a list item is a reference to a type T then the type
21042 // will be considered to be T for all purposes of this clause.
21043 if (CurType->isReferenceType())
21044 CurType = CurType->getPointeeType();
21045
21046 bool IsPointer = CurType->isAnyPointerType();
21047
21048 if (!IsPointer && !CurType->isArrayType()) {
21049 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21050 << 0 << OASE->getSourceRange();
21051 return false;
21052 }
21053
21054 bool NotWhole =
21055 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21056 bool NotUnity =
21057 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21058
21059 if (AllowWholeSizeArraySection) {
21060 // Any array section is currently allowed. Allowing a whole size array
21061 // section implies allowing a unity array section as well.
21062 //
21063 // If this array section refers to the whole dimension we can still
21064 // accept other array sections before this one, except if the base is a
21065 // pointer. Otherwise, only unitary sections are accepted.
21066 if (NotWhole || IsPointer)
21067 AllowWholeSizeArraySection = false;
21068 } else if (DKind == OMPD_target_update &&
21069 SemaRef.getLangOpts().OpenMP >= 50) {
21070 if (IsPointer && !AllowAnotherPtr)
21071 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21072 << /*array of unknown bound */ 1;
21073 else
21074 IsNonContiguous = true;
21075 } else if (AllowUnitySizeArraySection && NotUnity) {
21076 // A unity or whole array section is not allowed and that is not
21077 // compatible with the properties of the current array section.
21078 if (NoDiagnose)
21079 return false;
21080 SemaRef.Diag(ELoc,
21081 diag::err_array_section_does_not_specify_contiguous_storage)
21082 << OASE->getSourceRange();
21083 return false;
21084 }
21085
21086 if (IsPointer)
21087 AllowAnotherPtr = false;
21088
21089 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21090 Expr::EvalResult ResultR;
21091 Expr::EvalResult ResultL;
21092 if (!OASE->getLength()->isValueDependent() &&
21093 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21094 !ResultR.Val.getInt().isOne()) {
21095 SemaRef.Diag(OASE->getLength()->getExprLoc(),
21096 diag::err_omp_invalid_map_this_expr);
21097 SemaRef.Diag(OASE->getLength()->getExprLoc(),
21098 diag::note_omp_invalid_length_on_this_ptr_mapping);
21099 }
21100 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21101 OASE->getLowerBound()->EvaluateAsInt(ResultL,
21102 SemaRef.getASTContext()) &&
21103 !ResultL.Val.getInt().isZero()) {
21104 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21105 diag::err_omp_invalid_map_this_expr);
21106 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21107 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21108 }
21109 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", 21109, __extension__ __PRETTY_FUNCTION__
))
;
21110 RelevantExpr = TE;
21111 }
21112
21113 // Record the component - we don't have any declaration associated.
21114 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21115 return RelevantExpr || Visit(E);
21116 }
21117 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21118 Expr *Base = E->getBase();
21119
21120 // Record the component - we don't have any declaration associated.
21121 Components.emplace_back(E, nullptr, IsNonContiguous);
21122
21123 return Visit(Base->IgnoreParenImpCasts());
21124 }
21125
21126 bool VisitUnaryOperator(UnaryOperator *UO) {
21127 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21128 UO->getOpcode() != UO_Deref) {
21129 emitErrorMsg();
21130 return false;
21131 }
21132 if (!RelevantExpr) {
21133 // Record the component if haven't found base decl.
21134 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21135 }
21136 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21137 }
21138 bool VisitBinaryOperator(BinaryOperator *BO) {
21139 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21140 emitErrorMsg();
21141 return false;
21142 }
21143
21144 // Pointer arithmetic is the only thing we expect to happen here so after we
21145 // make sure the binary operator is a pointer type, the only thing we need
21146 // to do is to visit the subtree that has the same type as root (so that we
21147 // know the other subtree is just an offset)
21148 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21149 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21150 Components.emplace_back(BO, nullptr, false);
21151 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", 21153, __extension__ __PRETTY_FUNCTION__
))
21152 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", 21153, __extension__ __PRETTY_FUNCTION__
))
21153 "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", 21153, __extension__ __PRETTY_FUNCTION__
))
;
21154 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21155 return RelevantExpr || Visit(LE);
21156 return RelevantExpr || Visit(RE);
21157 }
21158 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21159 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", 21159, __extension__ __PRETTY_FUNCTION__
))
;
21160 RelevantExpr = CTE;
21161 Components.emplace_back(CTE, nullptr, IsNonContiguous);
21162 return true;
21163 }
21164 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21165 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", 21165, __extension__ __PRETTY_FUNCTION__
))
;
21166 Components.emplace_back(COCE, nullptr, IsNonContiguous);
21167 return true;
21168 }
21169 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21170 Expr *Source = E->getSourceExpr();
21171 if (!Source) {
21172 emitErrorMsg();
21173 return false;
21174 }
21175 return Visit(Source);
21176 }
21177 bool VisitStmt(Stmt *) {
21178 emitErrorMsg();
21179 return false;
21180 }
21181 const Expr *getFoundBase() const { return RelevantExpr; }
21182 explicit MapBaseChecker(
21183 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21184 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21185 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21186 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21187 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21188};
21189} // namespace
21190
21191/// Return the expression of the base of the mappable expression or null if it
21192/// cannot be determined and do all the necessary checks to see if the
21193/// expression is valid as a standalone mappable expression. In the process,
21194/// record all the components of the expression.
21195static const Expr *checkMapClauseExpressionBase(
21196 Sema &SemaRef, Expr *E,
21197 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21198 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21199 SourceLocation ELoc = E->getExprLoc();
21200 SourceRange ERange = E->getSourceRange();
21201 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21202 ERange);
21203 if (Checker.Visit(E->IgnoreParens())) {
21204 // Check if the highest dimension array section has length specified
21205 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21206 (CKind == OMPC_to || CKind == OMPC_from)) {
21207 auto CI = CurComponents.rbegin();
21208 auto CE = CurComponents.rend();
21209 for (; CI != CE; ++CI) {
21210 const auto *OASE =
21211 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21212 if (!OASE)
21213 continue;
21214 if (OASE && OASE->getLength())
21215 break;
21216 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21217 << ERange;
21218 }
21219 }
21220 return Checker.getFoundBase();
21221 }
21222 return nullptr;
21223}
21224
21225// Return true if expression E associated with value VD has conflicts with other
21226// map information.
21227static bool checkMapConflicts(
21228 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21229 bool CurrentRegionOnly,
21230 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21231 OpenMPClauseKind CKind) {
21232 assert(VD && E)(static_cast <bool> (VD && E) ? void (0) : __assert_fail
("VD && E", "clang/lib/Sema/SemaOpenMP.cpp", 21232, __extension__
__PRETTY_FUNCTION__))
;
21233 SourceLocation ELoc = E->getExprLoc();
21234 SourceRange ERange = E->getSourceRange();
21235
21236 // In order to easily check the conflicts we need to match each component of
21237 // the expression under test with the components of the expressions that are
21238 // already in the stack.
21239
21240 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", 21240, __extension__ __PRETTY_FUNCTION__
))
;
21241 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", 21242, __extension__ __PRETTY_FUNCTION__
))
21242 "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", 21242, __extension__ __PRETTY_FUNCTION__
))
;
21243
21244 // Variables to help detecting enclosing problems in data environment nests.
21245 bool IsEnclosedByDataEnvironmentExpr = false;
21246 const Expr *EnclosingExpr = nullptr;
21247
21248 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21249 VD, CurrentRegionOnly,
21250 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21251 ERange, CKind, &EnclosingExpr,
21252 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21253 StackComponents,
21254 OpenMPClauseKind Kind) {
21255 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21256 return false;
21257 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", 21258, __extension__ __PRETTY_FUNCTION__
))
21258 "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", 21258, __extension__ __PRETTY_FUNCTION__
))
;
21259 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", 21260, __extension__ __PRETTY_FUNCTION__
))
21260 "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", 21260, __extension__ __PRETTY_FUNCTION__
))
;
21261 (void)VD;
21262
21263 // The whole expression in the stack.
21264 const Expr *RE = StackComponents.front().getAssociatedExpression();
21265
21266 // Expressions must start from the same base. Here we detect at which
21267 // point both expressions diverge from each other and see if we can
21268 // detect if the memory referred to both expressions is contiguous and
21269 // do not overlap.
21270 auto CI = CurComponents.rbegin();
21271 auto CE = CurComponents.rend();
21272 auto SI = StackComponents.rbegin();
21273 auto SE = StackComponents.rend();
21274 for (; CI != CE && SI != SE; ++CI, ++SI) {
21275
21276 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21277 // At most one list item can be an array item derived from a given
21278 // variable in map clauses of the same construct.
21279 if (CurrentRegionOnly &&
21280 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21281 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21282 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21283 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21284 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21285 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21286 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21287 diag::err_omp_multiple_array_items_in_map_clause)
21288 << CI->getAssociatedExpression()->getSourceRange();
21289 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21290 diag::note_used_here)
21291 << SI->getAssociatedExpression()->getSourceRange();
21292 return true;
21293 }
21294
21295 // Do both expressions have the same kind?
21296 if (CI->getAssociatedExpression()->getStmtClass() !=
21297 SI->getAssociatedExpression()->getStmtClass())
21298 break;
21299
21300 // Are we dealing with different variables/fields?
21301 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21302 break;
21303 }
21304 // Check if the extra components of the expressions in the enclosing
21305 // data environment are redundant for the current base declaration.
21306 // If they are, the maps completely overlap, which is legal.
21307 for (; SI != SE; ++SI) {
21308 QualType Type;
21309 if (const auto *ASE =
21310 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21311 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21312 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21313 SI->getAssociatedExpression())) {
21314 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21315 Type =
21316 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21317 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21318 SI->getAssociatedExpression())) {
21319 Type = OASE->getBase()->getType()->getPointeeType();
21320 }
21321 if (Type.isNull() || Type->isAnyPointerType() ||
21322 checkArrayExpressionDoesNotReferToWholeSize(
21323 SemaRef, SI->getAssociatedExpression(), Type))
21324 break;
21325 }
21326
21327 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21328 // List items of map clauses in the same construct must not share
21329 // original storage.
21330 //
21331 // If the expressions are exactly the same or one is a subset of the
21332 // other, it means they are sharing storage.
21333 if (CI == CE && SI == SE) {
21334 if (CurrentRegionOnly) {
21335 if (CKind == OMPC_map) {
21336 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21337 } else {
21338 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", 21338, __extension__ __PRETTY_FUNCTION__
))
;
21339 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21340 << ERange;
21341 }
21342 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21343 << RE->getSourceRange();
21344 return true;
21345 }
21346 // If we find the same expression in the enclosing data environment,
21347 // that is legal.
21348 IsEnclosedByDataEnvironmentExpr = true;
21349 return false;
21350 }
21351
21352 QualType DerivedType =
21353 std::prev(CI)->getAssociatedDeclaration()->getType();
21354 SourceLocation DerivedLoc =
21355 std::prev(CI)->getAssociatedExpression()->getExprLoc();
21356
21357 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21358 // If the type of a list item is a reference to a type T then the type
21359 // will be considered to be T for all purposes of this clause.
21360 DerivedType = DerivedType.getNonReferenceType();
21361
21362 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21363 // A variable for which the type is pointer and an array section
21364 // derived from that variable must not appear as list items of map
21365 // clauses of the same construct.
21366 //
21367 // Also, cover one of the cases in:
21368 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21369 // If any part of the original storage of a list item has corresponding
21370 // storage in the device data environment, all of the original storage
21371 // must have corresponding storage in the device data environment.
21372 //
21373 if (DerivedType->isAnyPointerType()) {
21374 if (CI == CE || SI == SE) {
21375 SemaRef.Diag(
21376 DerivedLoc,
21377 diag::err_omp_pointer_mapped_along_with_derived_section)
21378 << DerivedLoc;
21379 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21380 << RE->getSourceRange();
21381 return true;
21382 }
21383 if (CI->getAssociatedExpression()->getStmtClass() !=
21384 SI->getAssociatedExpression()->getStmtClass() ||
21385 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21386 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21387 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"
, 21387, __extension__ __PRETTY_FUNCTION__))
;
21388 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21389 << DerivedLoc;
21390 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21391 << RE->getSourceRange();
21392 return true;
21393 }
21394 }
21395
21396 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21397 // List items of map clauses in the same construct must not share
21398 // original storage.
21399 //
21400 // An expression is a subset of the other.
21401 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21402 if (CKind == OMPC_map) {
21403 if (CI != CE || SI != SE) {
21404 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21405 // a pointer.
21406 auto Begin =
21407 CI != CE ? CurComponents.begin() : StackComponents.begin();
21408 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21409 auto It = Begin;
21410 while (It != End && !It->getAssociatedDeclaration())
21411 std::advance(It, 1);
21412 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", 21413, __extension__ __PRETTY_FUNCTION__
))
21413 "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", 21413, __extension__ __PRETTY_FUNCTION__
))
;
21414 if (It != Begin && It->getAssociatedDeclaration()
21415 ->getType()
21416 .getCanonicalType()
21417 ->isAnyPointerType()) {
21418 IsEnclosedByDataEnvironmentExpr = false;
21419 EnclosingExpr = nullptr;
21420 return false;
21421 }
21422 }
21423 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21424 } else {
21425 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", 21425, __extension__ __PRETTY_FUNCTION__
))
;
21426 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21427 << ERange;
21428 }
21429 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21430 << RE->getSourceRange();
21431 return true;
21432 }
21433
21434 // The current expression uses the same base as other expression in the
21435 // data environment but does not contain it completely.
21436 if (!CurrentRegionOnly && SI != SE)
21437 EnclosingExpr = RE;
21438
21439 // The current expression is a subset of the expression in the data
21440 // environment.
21441 IsEnclosedByDataEnvironmentExpr |=
21442 (!CurrentRegionOnly && CI != CE && SI == SE);
21443
21444 return false;
21445 });
21446
21447 if (CurrentRegionOnly)
21448 return FoundError;
21449
21450 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21451 // If any part of the original storage of a list item has corresponding
21452 // storage in the device data environment, all of the original storage must
21453 // have corresponding storage in the device data environment.
21454 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21455 // If a list item is an element of a structure, and a different element of
21456 // the structure has a corresponding list item in the device data environment
21457 // prior to a task encountering the construct associated with the map clause,
21458 // then the list item must also have a corresponding list item in the device
21459 // data environment prior to the task encountering the construct.
21460 //
21461 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21462 SemaRef.Diag(ELoc,
21463 diag::err_omp_original_storage_is_shared_and_does_not_contain)
21464 << ERange;
21465 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21466 << EnclosingExpr->getSourceRange();
21467 return true;
21468 }
21469
21470 return FoundError;
21471}
21472
21473// Look up the user-defined mapper given the mapper name and mapped type, and
21474// build a reference to it.
21475static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21476 CXXScopeSpec &MapperIdScopeSpec,
21477 const DeclarationNameInfo &MapperId,
21478 QualType Type,
21479 Expr *UnresolvedMapper) {
21480 if (MapperIdScopeSpec.isInvalid())
21481 return ExprError();
21482 // Get the actual type for the array type.
21483 if (Type->isArrayType()) {
21484 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", 21484, __extension__ __PRETTY_FUNCTION__
))
;
21485 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21486 }
21487 // Find all user-defined mappers with the given MapperId.
21488 SmallVector<UnresolvedSet<8>, 4> Lookups;
21489 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21490 Lookup.suppressDiagnostics();
21491 if (S) {
21492 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21493 NamedDecl *D = Lookup.getRepresentativeDecl();
21494 while (S && !S->isDeclScope(D))
21495 S = S->getParent();
21496 if (S)
21497 S = S->getParent();
21498 Lookups.emplace_back();
21499 Lookups.back().append(Lookup.begin(), Lookup.end());
21500 Lookup.clear();
21501 }
21502 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21503 // Extract the user-defined mappers with the given MapperId.
21504 Lookups.push_back(UnresolvedSet<8>());
21505 for (NamedDecl *D : ULE->decls()) {
21506 auto *DMD = cast<OMPDeclareMapperDecl>(D);
21507 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", 21507, __extension__ __PRETTY_FUNCTION__
))
;
21508 Lookups.back().addDecl(DMD);
21509 }
21510 }
21511 // Defer the lookup for dependent types. The results will be passed through
21512 // UnresolvedMapper on instantiation.
21513 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21514 Type->isInstantiationDependentType() ||
21515 Type->containsUnexpandedParameterPack() ||
21516 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21517 return !D->isInvalidDecl() &&
21518 (D->getType()->isDependentType() ||
21519 D->getType()->isInstantiationDependentType() ||
21520 D->getType()->containsUnexpandedParameterPack());
21521 })) {
21522 UnresolvedSet<8> URS;
21523 for (const UnresolvedSet<8> &Set : Lookups) {
21524 if (Set.empty())
21525 continue;
21526 URS.append(Set.begin(), Set.end());
21527 }
21528 return UnresolvedLookupExpr::Create(
21529 SemaRef.Context, /*NamingClass=*/nullptr,
21530 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21531 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21532 }
21533 SourceLocation Loc = MapperId.getLoc();
21534 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21535 // The type must be of struct, union or class type in C and C++
21536 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21537 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21538 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21539 return ExprError();
21540 }
21541 // Perform argument dependent lookup.
21542 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21543 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21544 // Return the first user-defined mapper with the desired type.
21545 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21546 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21547 if (!D->isInvalidDecl() &&
21548 SemaRef.Context.hasSameType(D->getType(), Type))
21549 return D;
21550 return nullptr;
21551 }))
21552 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21553 // Find the first user-defined mapper with a type derived from the desired
21554 // type.
21555 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21556 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21557 if (!D->isInvalidDecl() &&
21558 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21559 !Type.isMoreQualifiedThan(D->getType()))
21560 return D;
21561 return nullptr;
21562 })) {
21563 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21564 /*DetectVirtual=*/false);
21565 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21566 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21567 VD->getType().getUnqualifiedType()))) {
21568 if (SemaRef.CheckBaseClassAccess(
21569 Loc, VD->getType(), Type, Paths.front(),
21570 /*DiagID=*/0) != Sema::AR_inaccessible) {
21571 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21572 }
21573 }
21574 }
21575 }
21576 // Report error if a mapper is specified, but cannot be found.
21577 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
21578 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21579 << Type << MapperId.getName();
21580 return ExprError();
21581 }
21582 return ExprEmpty();
21583}
21584
21585namespace {
21586// Utility struct that gathers all the related lists associated with a mappable
21587// expression.
21588struct MappableVarListInfo {
21589 // The list of expressions.
21590 ArrayRef<Expr *> VarList;
21591 // The list of processed expressions.
21592 SmallVector<Expr *, 16> ProcessedVarList;
21593 // The mappble components for each expression.
21594 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
21595 // The base declaration of the variable.
21596 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
21597 // The reference to the user-defined mapper associated with every expression.
21598 SmallVector<Expr *, 16> UDMapperList;
21599
21600 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
21601 // We have a list of components and base declarations for each entry in the
21602 // variable list.
21603 VarComponents.reserve(VarList.size());
21604 VarBaseDeclarations.reserve(VarList.size());
21605 }
21606};
21607} // namespace
21608
21609// Check the validity of the provided variable list for the provided clause kind
21610// \a CKind. In the check process the valid expressions, mappable expression
21611// components, variables, and user-defined mappers are extracted and used to
21612// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21613// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21614// and \a MapperId are expected to be valid if the clause kind is 'map'.
21615static void checkMappableExpressionList(
21616 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
21617 MappableVarListInfo &MVLI, SourceLocation StartLoc,
21618 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
21619 ArrayRef<Expr *> UnresolvedMappers,
21620 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
21621 ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
21622 bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
21623 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21624 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", 21625, __extension__ __PRETTY_FUNCTION__
))
21625 "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", 21625, __extension__ __PRETTY_FUNCTION__
))
;
21626
21627 // If the identifier of user-defined mapper is not specified, it is "default".
21628 // We do not change the actual name in this clause to distinguish whether a
21629 // mapper is specified explicitly, i.e., it is not explicitly specified when
21630 // MapperId.getName() is empty.
21631 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
21632 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
21633 MapperId.setName(DeclNames.getIdentifier(
21634 &SemaRef.getASTContext().Idents.get("default")));
21635 MapperId.setLoc(StartLoc);
21636 }
21637
21638 // Iterators to find the current unresolved mapper expression.
21639 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21640 bool UpdateUMIt = false;
21641 Expr *UnresolvedMapper = nullptr;
21642
21643 bool HasHoldModifier =
21644 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21645
21646 // Keep track of the mappable components and base declarations in this clause.
21647 // Each entry in the list is going to have a list of components associated. We
21648 // record each set of the components so that we can build the clause later on.
21649 // In the end we should have the same amount of declarations and component
21650 // lists.
21651
21652 for (Expr *RE : MVLI.VarList) {
21653 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", 21653, __extension__ __PRETTY_FUNCTION__
))
;
21654 SourceLocation ELoc = RE->getExprLoc();
21655
21656 // Find the current unresolved mapper expression.
21657 if (UpdateUMIt && UMIt != UMEnd) {
21658 UMIt++;
21659 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", 21661, __extension__ __PRETTY_FUNCTION__
))
21660 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", 21661, __extension__ __PRETTY_FUNCTION__
))
21661 "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", 21661, __extension__ __PRETTY_FUNCTION__
))
;
21662 }
21663 UpdateUMIt = true;
21664 if (UMIt != UMEnd)
21665 UnresolvedMapper = *UMIt;
21666
21667 const Expr *VE = RE->IgnoreParenLValueCasts();
21668
21669 if (VE->isValueDependent() || VE->isTypeDependent() ||
21670 VE->isInstantiationDependent() ||
21671 VE->containsUnexpandedParameterPack()) {
21672 // Try to find the associated user-defined mapper.
21673 ExprResult ER = buildUserDefinedMapperRef(
21674 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21675 VE->getType().getCanonicalType(), UnresolvedMapper);
21676 if (ER.isInvalid())
21677 continue;
21678 MVLI.UDMapperList.push_back(ER.get());
21679 // We can only analyze this information once the missing information is
21680 // resolved.
21681 MVLI.ProcessedVarList.push_back(RE);
21682 continue;
21683 }
21684
21685 Expr *SimpleExpr = RE->IgnoreParenCasts();
21686
21687 if (!RE->isLValue()) {
21688 if (SemaRef.getLangOpts().OpenMP < 50) {
21689 SemaRef.Diag(
21690 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21691 << RE->getSourceRange();
21692 } else {
21693 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21694 << getOpenMPClauseName(CKind) << RE->getSourceRange();
21695 }
21696 continue;
21697 }
21698
21699 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
21700 ValueDecl *CurDeclaration = nullptr;
21701
21702 // Obtain the array or member expression bases if required. Also, fill the
21703 // components array with all the components identified in the process.
21704 const Expr *BE =
21705 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
21706 DSAS->getCurrentDirective(), NoDiagnose);
21707 if (!BE)
21708 continue;
21709
21710 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", 21711, __extension__ __PRETTY_FUNCTION__
))
21711 "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", 21711, __extension__ __PRETTY_FUNCTION__
))
;
21712
21713 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21714 // Add store "this" pointer to class in DSAStackTy for future checking
21715 DSAS->addMappedClassesQualTypes(TE->getType());
21716 // Try to find the associated user-defined mapper.
21717 ExprResult ER = buildUserDefinedMapperRef(
21718 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21719 VE->getType().getCanonicalType(), UnresolvedMapper);
21720 if (ER.isInvalid())
21721 continue;
21722 MVLI.UDMapperList.push_back(ER.get());
21723 // Skip restriction checking for variable or field declarations
21724 MVLI.ProcessedVarList.push_back(RE);
21725 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21726 MVLI.VarComponents.back().append(CurComponents.begin(),
21727 CurComponents.end());
21728 MVLI.VarBaseDeclarations.push_back(nullptr);
21729 continue;
21730 }
21731
21732 // For the following checks, we rely on the base declaration which is
21733 // expected to be associated with the last component. The declaration is
21734 // expected to be a variable or a field (if 'this' is being mapped).
21735 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21736 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", 21736, __extension__ __PRETTY_FUNCTION__
))
;
21737 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", 21739, __extension__ __PRETTY_FUNCTION__
))
21738 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", 21739, __extension__ __PRETTY_FUNCTION__
))
21739 "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", 21739, __extension__ __PRETTY_FUNCTION__
))
;
21740
21741 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21742 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21743
21744 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", 21744, __extension__ __PRETTY_FUNCTION__
))
;
21745 (void)FD;
21746
21747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21748 // threadprivate variables cannot appear in a map clause.
21749 // OpenMP 4.5 [2.10.5, target update Construct]
21750 // threadprivate variables cannot appear in a from clause.
21751 if (VD && DSAS->isThreadPrivate(VD)) {
21752 if (NoDiagnose)
21753 continue;
21754 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21755 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21756 << getOpenMPClauseName(CKind);
21757 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
21758 continue;
21759 }
21760
21761 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21762 // A list item cannot appear in both a map clause and a data-sharing
21763 // attribute clause on the same construct.
21764
21765 // Check conflicts with other map clause expressions. We check the conflicts
21766 // with the current construct separately from the enclosing data
21767 // environment, because the restrictions are different. We only have to
21768 // check conflicts across regions for the map clauses.
21769 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21770 /*CurrentRegionOnly=*/true, CurComponents, CKind))
21771 break;
21772 if (CKind == OMPC_map &&
21773 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
21774 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21775 /*CurrentRegionOnly=*/false, CurComponents, CKind))
21776 break;
21777
21778 // OpenMP 4.5 [2.10.5, target update Construct]
21779 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21780 // If the type of a list item is a reference to a type T then the type will
21781 // be considered to be T for all purposes of this clause.
21782 auto I = llvm::find_if(
21783 CurComponents,
21784 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
21785 return MC.getAssociatedDeclaration();
21786 });
21787 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", 21787, __extension__ __PRETTY_FUNCTION__
))
;
21788 (void)I;
21789 QualType Type;
21790 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
21791 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
21792 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
21793 if (ASE) {
21794 Type = ASE->getType().getNonReferenceType();
21795 } else if (OASE) {
21796 QualType BaseType =
21797 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21798 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21799 Type = ATy->getElementType();
21800 else
21801 Type = BaseType->getPointeeType();
21802 Type = Type.getNonReferenceType();
21803 } else if (OAShE) {
21804 Type = OAShE->getBase()->getType()->getPointeeType();
21805 } else {
21806 Type = VE->getType();
21807 }
21808
21809 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21810 // A list item in a to or from clause must have a mappable type.
21811 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21812 // A list item must have a mappable type.
21813 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21814 DSAS, Type, /*FullCheck=*/true))
21815 continue;
21816
21817 if (CKind == OMPC_map) {
21818 // target enter data
21819 // OpenMP [2.10.2, Restrictions, p. 99]
21820 // A map-type must be specified in all map clauses and must be either
21821 // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
21822 // no map type is present.
21823 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21824 if (DKind == OMPD_target_enter_data &&
21825 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
21826 SemaRef.getLangOpts().OpenMP >= 52)) {
21827 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21828 << (IsMapTypeImplicit ? 1 : 0)
21829 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21830 << getOpenMPDirectiveName(DKind);
21831 continue;
21832 }
21833
21834 // target exit_data
21835 // OpenMP [2.10.3, Restrictions, p. 102]
21836 // A map-type must be specified in all map clauses and must be either
21837 // from, release, or delete. Starting with OpenMP 5.2 the default map
21838 // type is `from` if no map type is present.
21839 if (DKind == OMPD_target_exit_data &&
21840 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21841 MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
21842 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21843 << (IsMapTypeImplicit ? 1 : 0)
21844 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21845 << getOpenMPDirectiveName(DKind);
21846 continue;
21847 }
21848
21849 // The 'ompx_hold' modifier is specifically intended to be used on a
21850 // 'target' or 'target data' directive to prevent data from being unmapped
21851 // during the associated statement. It is not permitted on a 'target
21852 // enter data' or 'target exit data' directive, which have no associated
21853 // statement.
21854 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21855 HasHoldModifier) {
21856 SemaRef.Diag(StartLoc,
21857 diag::err_omp_invalid_map_type_modifier_for_directive)
21858 << getOpenMPSimpleClauseTypeName(OMPC_map,
21859 OMPC_MAP_MODIFIER_ompx_hold)
21860 << getOpenMPDirectiveName(DKind);
21861 continue;
21862 }
21863
21864 // target, target data
21865 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21866 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21867 // A map-type in a map clause must be to, from, tofrom or alloc
21868 if ((DKind == OMPD_target_data ||
21869 isOpenMPTargetExecutionDirective(DKind)) &&
21870 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21871 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21872 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21873 << (IsMapTypeImplicit ? 1 : 0)
21874 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21875 << getOpenMPDirectiveName(DKind);
21876 continue;
21877 }
21878
21879 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21880 // A list item cannot appear in both a map clause and a data-sharing
21881 // attribute clause on the same construct
21882 //
21883 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21884 // A list item cannot appear in both a map clause and a data-sharing
21885 // attribute clause on the same construct unless the construct is a
21886 // combined construct.
21887 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21888 isOpenMPTargetExecutionDirective(DKind)) ||
21889 DKind == OMPD_target)) {
21890 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21891 if (isOpenMPPrivate(DVar.CKind)) {
21892 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21893 << getOpenMPClauseName(DVar.CKind)
21894 << getOpenMPClauseName(OMPC_map)
21895 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21896 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21897 continue;
21898 }
21899 }
21900 }
21901
21902 // Try to find the associated user-defined mapper.
21903 ExprResult ER = buildUserDefinedMapperRef(
21904 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21905 Type.getCanonicalType(), UnresolvedMapper);
21906 if (ER.isInvalid())
21907 continue;
21908 MVLI.UDMapperList.push_back(ER.get());
21909
21910 // Save the current expression.
21911 MVLI.ProcessedVarList.push_back(RE);
21912
21913 // Store the components in the stack so that they can be used to check
21914 // against other clauses later on.
21915 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21916 /*WhereFoundClauseKind=*/OMPC_map);
21917
21918 // Save the components and declaration to create the clause. For purposes of
21919 // the clause creation, any component list that has base 'this' uses
21920 // null as base declaration.
21921 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21922 MVLI.VarComponents.back().append(CurComponents.begin(),
21923 CurComponents.end());
21924 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
21925 : CurDeclaration);
21926 }
21927}
21928
21929OMPClause *Sema::ActOnOpenMPMapClause(
21930 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
21931 ArrayRef<SourceLocation> MapTypeModifiersLoc,
21932 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21933 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
21934 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21935 const OMPVarListLocTy &Locs, bool NoDiagnose,
21936 ArrayRef<Expr *> UnresolvedMappers) {
21937 OpenMPMapModifierKind Modifiers[] = {
21938 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21939 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21940 OMPC_MAP_MODIFIER_unknown};
21941 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
21942
21943 // Process map-type-modifiers, flag errors for duplicate modifiers.
21944 unsigned Count = 0;
21945 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21946 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
21947 llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21948 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21949 continue;
21950 }
21951 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", 21952, __extension__ __PRETTY_FUNCTION__
))
21952 "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", 21952, __extension__ __PRETTY_FUNCTION__
))
;
21953 Modifiers[Count] = MapTypeModifiers[I];
21954 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21955 ++Count;
21956 }
21957
21958 MappableVarListInfo MVLI(VarList);
21959 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
21960 MapperIdScopeSpec, MapperId, UnresolvedMappers,
21961 MapType, Modifiers, IsMapTypeImplicit,
21962 NoDiagnose);
21963
21964 // We need to produce a map clause even if we don't have variables so that
21965 // other diagnostics related with non-existing map clauses are accurate.
21966 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
21967 MVLI.VarBaseDeclarations, MVLI.VarComponents,
21968 MVLI.UDMapperList, Modifiers, ModifiersLoc,
21969 MapperIdScopeSpec.getWithLocInContext(Context),
21970 MapperId, MapType, IsMapTypeImplicit, MapLoc);
21971}
21972
21973QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
21974 TypeResult ParsedType) {
21975 assert(ParsedType.isUsable())(static_cast <bool> (ParsedType.isUsable()) ? void (0) :
__assert_fail ("ParsedType.isUsable()", "clang/lib/Sema/SemaOpenMP.cpp"
, 21975, __extension__ __PRETTY_FUNCTION__))
;
21976
21977 QualType ReductionType = GetTypeFromParser(ParsedType.get());
21978 if (ReductionType.isNull())
21979 return QualType();
21980
21981 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21982 // A type name in a declare reduction directive cannot be a function type, an
21983 // array type, a reference type, or a type qualified with const, volatile or
21984 // restrict.
21985 if (ReductionType.hasQualifiers()) {
21986 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21987 return QualType();
21988 }
21989
21990 if (ReductionType->isFunctionType()) {
21991 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21992 return QualType();
21993 }
21994 if (ReductionType->isReferenceType()) {
21995 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21996 return QualType();
21997 }
21998 if (ReductionType->isArrayType()) {
21999 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22000 return QualType();
22001 }
22002 return ReductionType;
22003}
22004
22005Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22006 Scope *S, DeclContext *DC, DeclarationName Name,
22007 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22008 AccessSpecifier AS, Decl *PrevDeclInScope) {
22009 SmallVector<Decl *, 8> Decls;
22010 Decls.reserve(ReductionTypes.size());
22011
22012 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22013 forRedeclarationInCurContext());
22014 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22015 // A reduction-identifier may not be re-declared in the current scope for the
22016 // same type or for a type that is compatible according to the base language
22017 // rules.
22018 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22019 OMPDeclareReductionDecl *PrevDRD = nullptr;
22020 bool InCompoundScope = true;
22021 if (S != nullptr) {
22022 // Find previous declaration with the same name not referenced in other
22023 // declarations.
22024 FunctionScopeInfo *ParentFn = getEnclosingFunction();
22025 InCompoundScope =
22026 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22027 LookupName(Lookup, S);
22028 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22029 /*AllowInlineNamespace=*/false);
22030 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22031 LookupResult::Filter Filter = Lookup.makeFilter();
22032 while (Filter.hasNext()) {
22033 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22034 if (InCompoundScope) {
22035 auto I = UsedAsPrevious.find(PrevDecl);
22036 if (I == UsedAsPrevious.end())
22037 UsedAsPrevious[PrevDecl] = false;
22038 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22039 UsedAsPrevious[D] = true;
22040 }
22041 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22042 PrevDecl->getLocation();
22043 }
22044 Filter.done();
22045 if (InCompoundScope) {
22046 for (const auto &PrevData : UsedAsPrevious) {
22047 if (!PrevData.second) {
22048 PrevDRD = PrevData.first;
22049 break;
22050 }
22051 }
22052 }
22053 } else if (PrevDeclInScope != nullptr) {
22054 auto *PrevDRDInScope = PrevDRD =
22055 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22056 do {
22057 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22058 PrevDRDInScope->getLocation();
22059 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22060 } while (PrevDRDInScope != nullptr);
22061 }
22062 for (const auto &TyData : ReductionTypes) {
22063 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22064 bool Invalid = false;
22065 if (I != PreviousRedeclTypes.end()) {
22066 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22067 << TyData.first;
22068 Diag(I->second, diag::note_previous_definition);
22069 Invalid = true;
22070 }
22071 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22072 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22073 Name, TyData.first, PrevDRD);
22074 DC->addDecl(DRD);
22075 DRD->setAccess(AS);
22076 Decls.push_back(DRD);
22077 if (Invalid)
22078 DRD->setInvalidDecl();
22079 else
22080 PrevDRD = DRD;
22081 }
22082
22083 return DeclGroupPtrTy::make(
22084 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22085}
22086
22087void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22088 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22089
22090 // Enter new function scope.
22091 PushFunctionScope();
22092 setFunctionHasBranchProtectedScope();
22093 getCurFunction()->setHasOMPDeclareReductionCombiner();
22094
22095 if (S != nullptr)
22096 PushDeclContext(S, DRD);
22097 else
22098 CurContext = DRD;
22099
22100 PushExpressionEvaluationContext(
22101 ExpressionEvaluationContext::PotentiallyEvaluated);
22102
22103 QualType ReductionType = DRD->getType();
22104 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22105 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22106 // uses semantics of argument handles by value, but it should be passed by
22107 // reference. C lang does not support references, so pass all parameters as
22108 // pointers.
22109 // Create 'T omp_in;' variable.
22110 VarDecl *OmpInParm =
22111 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22112 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22113 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22114 // uses semantics of argument handles by value, but it should be passed by
22115 // reference. C lang does not support references, so pass all parameters as
22116 // pointers.
22117 // Create 'T omp_out;' variable.
22118 VarDecl *OmpOutParm =
22119 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22120 if (S != nullptr) {
22121 PushOnScopeChains(OmpInParm, S);
22122 PushOnScopeChains(OmpOutParm, S);
22123 } else {
22124 DRD->addDecl(OmpInParm);
22125 DRD->addDecl(OmpOutParm);
22126 }
22127 Expr *InE =
22128 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22129 Expr *OutE =
22130 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22131 DRD->setCombinerData(InE, OutE);
22132}
22133
22134void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22135 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22136 DiscardCleanupsInEvaluationContext();
22137 PopExpressionEvaluationContext();
22138
22139 PopDeclContext();
22140 PopFunctionScopeInfo();
22141
22142 if (Combiner != nullptr)
22143 DRD->setCombiner(Combiner);
22144 else
22145 DRD->setInvalidDecl();
22146}
22147
22148VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22149 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22150
22151 // Enter new function scope.
22152 PushFunctionScope();
22153 setFunctionHasBranchProtectedScope();
22154
22155 if (S != nullptr)
22156 PushDeclContext(S, DRD);
22157 else
22158 CurContext = DRD;
22159
22160 PushExpressionEvaluationContext(
22161 ExpressionEvaluationContext::PotentiallyEvaluated);
22162
22163 QualType ReductionType = DRD->getType();
22164 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22165 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22166 // uses semantics of argument handles by value, but it should be passed by
22167 // reference. C lang does not support references, so pass all parameters as
22168 // pointers.
22169 // Create 'T omp_priv;' variable.
22170 VarDecl *OmpPrivParm =
22171 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22172 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22173 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22174 // uses semantics of argument handles by value, but it should be passed by
22175 // reference. C lang does not support references, so pass all parameters as
22176 // pointers.
22177 // Create 'T omp_orig;' variable.
22178 VarDecl *OmpOrigParm =
22179 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22180 if (S != nullptr) {
22181 PushOnScopeChains(OmpPrivParm, S);
22182 PushOnScopeChains(OmpOrigParm, S);
22183 } else {
22184 DRD->addDecl(OmpPrivParm);
22185 DRD->addDecl(OmpOrigParm);
22186 }
22187 Expr *OrigE =
22188 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22189 Expr *PrivE =
22190 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22191 DRD->setInitializerData(OrigE, PrivE);
22192 return OmpPrivParm;
22193}
22194
22195void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22196 VarDecl *OmpPrivParm) {
22197 auto *DRD = cast<OMPDeclareReductionDecl>(D);
22198 DiscardCleanupsInEvaluationContext();
22199 PopExpressionEvaluationContext();
22200
22201 PopDeclContext();
22202 PopFunctionScopeInfo();
22203
22204 if (Initializer != nullptr) {
22205 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
22206 } else if (OmpPrivParm->hasInit()) {
22207 DRD->setInitializer(OmpPrivParm->getInit(),
22208 OmpPrivParm->isDirectInit()
22209 ? OMPDeclareReductionDecl::DirectInit
22210 : OMPDeclareReductionDecl::CopyInit);
22211 } else {
22212 DRD->setInvalidDecl();
22213 }
22214}
22215
22216Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22217 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22218 for (Decl *D : DeclReductions.get()) {
22219 if (IsValid) {
22220 if (S)
22221 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22222 /*AddToContext=*/false);
22223 } else {
22224 D->setInvalidDecl();
22225 }
22226 }
22227 return DeclReductions;
22228}
22229
22230TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22231 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22232 QualType T = TInfo->getType();
22233 if (D.isInvalidType())
22234 return true;
22235
22236 if (getLangOpts().CPlusPlus) {
22237 // Check that there are no default arguments (C++ only).
22238 CheckExtraCXXDefaultArguments(D);
22239 }
22240
22241 return CreateParsedType(T, TInfo);
22242}
22243
22244QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22245 TypeResult ParsedType) {
22246 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", 22246, __extension__ __PRETTY_FUNCTION__
))
;
22247
22248 QualType MapperType = GetTypeFromParser(ParsedType.get());
22249 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", 22249, __extension__ __PRETTY_FUNCTION__
))
;
22250
22251 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22252 // The type must be of struct, union or class type in C and C++
22253 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22254 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22255 return QualType();
22256 }
22257 return MapperType;
22258}
22259
22260Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22261 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22262 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22263 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22264 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22265 forRedeclarationInCurContext());
22266 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22267 // A mapper-identifier may not be redeclared in the current scope for the
22268 // same type or for a type that is compatible according to the base language
22269 // rules.
22270 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22271 OMPDeclareMapperDecl *PrevDMD = nullptr;
22272 bool InCompoundScope = true;
22273 if (S != nullptr) {
22274 // Find previous declaration with the same name not referenced in other
22275 // declarations.
22276 FunctionScopeInfo *ParentFn = getEnclosingFunction();
22277 InCompoundScope =
22278 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22279 LookupName(Lookup, S);
22280 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22281 /*AllowInlineNamespace=*/false);
22282 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22283 LookupResult::Filter Filter = Lookup.makeFilter();
22284 while (Filter.hasNext()) {
22285 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22286 if (InCompoundScope) {
22287 auto I = UsedAsPrevious.find(PrevDecl);
22288 if (I == UsedAsPrevious.end())
22289 UsedAsPrevious[PrevDecl] = false;
22290 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22291 UsedAsPrevious[D] = true;
22292 }
22293 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22294 PrevDecl->getLocation();
22295 }
22296 Filter.done();
22297 if (InCompoundScope) {
22298 for (const auto &PrevData : UsedAsPrevious) {
22299 if (!PrevData.second) {
22300 PrevDMD = PrevData.first;
22301 break;
22302 }
22303 }
22304 }
22305 } else if (PrevDeclInScope) {
22306 auto *PrevDMDInScope = PrevDMD =
22307 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22308 do {
22309 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22310 PrevDMDInScope->getLocation();
22311 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22312 } while (PrevDMDInScope != nullptr);
22313 }
22314 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22315 bool Invalid = false;
22316 if (I != PreviousRedeclTypes.end()) {
22317 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22318 << MapperType << Name;
22319 Diag(I->second, diag::note_previous_definition);
22320 Invalid = true;
22321 }
22322 // Build expressions for implicit maps of data members with 'default'
22323 // mappers.
22324 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22325 Clauses.end());
22326 if (LangOpts.OpenMP >= 50)
22327 processImplicitMapsWithDefaultMappers(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ClausesWithImplicit);
22328 auto *DMD =
22329 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22330 ClausesWithImplicit, PrevDMD);
22331 if (S)
22332 PushOnScopeChains(DMD, S);
22333 else
22334 DC->addDecl(DMD);
22335 DMD->setAccess(AS);
22336 if (Invalid)
22337 DMD->setInvalidDecl();
22338
22339 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22340 VD->setDeclContext(DMD);
22341 VD->setLexicalDeclContext(DMD);
22342 DMD->addDecl(VD);
22343 DMD->setMapperVarRef(MapperVarRef);
22344
22345 return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22346}
22347
22348ExprResult
22349Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22350 SourceLocation StartLoc,
22351 DeclarationName VN) {
22352 TypeSourceInfo *TInfo =
22353 Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22354 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22355 StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22356 MapperType, TInfo, SC_None);
22357 if (S)
22358 PushOnScopeChains(VD, S, /*AddToContext=*/false);
22359 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22360 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDeclareMapperVarRef(E);
22361 return E;
22362}
22363
22364bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22365 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", 22365, __extension__ __PRETTY_FUNCTION__
))
;
22366 const Expr *Ref = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef();
22367 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22368 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22369 return true;
22370 if (VD->isUsableInConstantExpressions(Context))
22371 return true;
22372 return false;
22373 }
22374 return true;
22375}
22376
22377const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22378 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", 22378, __extension__ __PRETTY_FUNCTION__
))
;
22379 return cast<DeclRefExpr>(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDeclareMapperVarRef())->getDecl();
22380}
22381
22382OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22383 SourceLocation StartLoc,
22384 SourceLocation LParenLoc,
22385 SourceLocation EndLoc) {
22386 Expr *ValExpr = NumTeams;
22387 Stmt *HelperValStmt = nullptr;
22388
22389 // OpenMP [teams Constrcut, Restrictions]
22390 // The num_teams expression must evaluate to a positive integer value.
22391 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22392 /*StrictlyPositive=*/true))
22393 return nullptr;
22394
22395 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
22396 OpenMPDirectiveKind CaptureRegion =
22397 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22398 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22399 ValExpr = MakeFullExpr(ValExpr).get();
22400 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22401 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22402 HelperValStmt = buildPreInits(Context, Captures);
22403 }
22404
22405 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22406 StartLoc, LParenLoc, EndLoc);
22407}
22408
22409OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22410 SourceLocation StartLoc,
22411 SourceLocation LParenLoc,
22412 SourceLocation EndLoc) {
22413 Expr *ValExpr = ThreadLimit;
22414 Stmt *HelperValStmt = nullptr;
22415
22416 // OpenMP [teams Constrcut, Restrictions]
22417 // The thread_limit expression must evaluate to a positive integer value.
22418 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22419 /*StrictlyPositive=*/true))
22420 return nullptr;
22421
22422 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
22423 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22424 DKind, OMPC_thread_limit, LangOpts.OpenMP);
22425 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22426 ValExpr = MakeFullExpr(ValExpr).get();
22427 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22428 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22429 HelperValStmt = buildPreInits(Context, Captures);
22430 }
22431
22432 return new (Context) OMPThreadLimitClause(
22433 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22434}
22435
22436OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22437 SourceLocation StartLoc,
22438 SourceLocation LParenLoc,
22439 SourceLocation EndLoc) {
22440 Expr *ValExpr = Priority;
22441 Stmt *HelperValStmt = nullptr;
22442 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22443
22444 // OpenMP [2.9.1, task Constrcut]
22445 // The priority-value is a non-negative numerical scalar expression.
22446 if (!isNonNegativeIntegerValue(
22447 ValExpr, *this, OMPC_priority,
22448 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22449 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22450 return nullptr;
22451
22452 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22453 StartLoc, LParenLoc, EndLoc);
22454}
22455
22456OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22457 OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22458 SourceLocation StartLoc, SourceLocation LParenLoc,
22459 SourceLocation ModifierLoc, SourceLocation EndLoc) {
22460 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 51) && "Unexpected grainsize modifier in OpenMP < 51."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && \"Unexpected grainsize modifier in OpenMP < 51.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22461, __extension__ __PRETTY_FUNCTION__
))
22461 "Unexpected grainsize modifier in OpenMP < 51.")(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 51) && "Unexpected grainsize modifier in OpenMP < 51."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && \"Unexpected grainsize modifier in OpenMP < 51.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22461, __extension__ __PRETTY_FUNCTION__
))
;
22462
22463 if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22464 std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22465 OMPC_GRAINSIZE_unknown);
22466 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22467 << Values << getOpenMPClauseName(OMPC_grainsize);
22468 return nullptr;
22469 }
22470
22471 Expr *ValExpr = Grainsize;
22472 Stmt *HelperValStmt = nullptr;
22473 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22474
22475 // OpenMP [2.9.2, taskloop Constrcut]
22476 // The parameter of the grainsize clause must be a positive integer
22477 // expression.
22478 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22479 /*StrictlyPositive=*/true,
22480 /*BuildCapture=*/true,
22481 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(),
22482 &CaptureRegion, &HelperValStmt))
22483 return nullptr;
22484
22485 return new (Context)
22486 OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22487 StartLoc, LParenLoc, ModifierLoc, EndLoc);
22488}
22489
22490OMPClause *Sema::ActOnOpenMPNumTasksClause(
22491 OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22492 SourceLocation StartLoc, SourceLocation LParenLoc,
22493 SourceLocation ModifierLoc, SourceLocation EndLoc) {
22494 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 51) && "Unexpected num_tasks modifier in OpenMP < 51."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && \"Unexpected num_tasks modifier in OpenMP < 51.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22495, __extension__ __PRETTY_FUNCTION__
))
22495 "Unexpected num_tasks modifier in OpenMP < 51.")(static_cast <bool> ((ModifierLoc.isInvalid() || LangOpts
.OpenMP >= 51) && "Unexpected num_tasks modifier in OpenMP < 51."
) ? void (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) && \"Unexpected num_tasks modifier in OpenMP < 51.\""
, "clang/lib/Sema/SemaOpenMP.cpp", 22495, __extension__ __PRETTY_FUNCTION__
))
;
22496
22497 if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22498 std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22499 OMPC_NUMTASKS_unknown);
22500 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22501 << Values << getOpenMPClauseName(OMPC_num_tasks);
22502 return nullptr;
22503 }
22504
22505 Expr *ValExpr = NumTasks;
22506 Stmt *HelperValStmt = nullptr;
22507 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22508
22509 // OpenMP [2.9.2, taskloop Constrcut]
22510 // The parameter of the num_tasks clause must be a positive integer
22511 // expression.
22512 if (!isNonNegativeIntegerValue(
22513 ValExpr, *this, OMPC_num_tasks,
22514 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22515 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22516 return nullptr;
22517
22518 return new (Context)
22519 OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22520 StartLoc, LParenLoc, ModifierLoc, EndLoc);
22521}
22522
22523OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
22524 SourceLocation LParenLoc,
22525 SourceLocation EndLoc) {
22526 // OpenMP [2.13.2, critical construct, Description]
22527 // ... where hint-expression is an integer constant expression that evaluates
22528 // to a valid lock hint.
22529 ExprResult HintExpr =
22530 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22531 if (HintExpr.isInvalid())
22532 return nullptr;
22533 return new (Context)
22534 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22535}
22536
22537/// Tries to find omp_event_handle_t type.
22538static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
22539 DSAStackTy *Stack) {
22540 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22541 if (!OMPEventHandleT.isNull())
22542 return true;
22543 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22544 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22545 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22546 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22547 return false;
22548 }
22549 Stack->setOMPEventHandleT(PT.get());
22550 return true;
22551}
22552
22553OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
22554 SourceLocation LParenLoc,
22555 SourceLocation EndLoc) {
22556 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
22557 !Evt->isInstantiationDependent() &&
22558 !Evt->containsUnexpandedParameterPack()) {
22559 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
22560 return nullptr;
22561 // OpenMP 5.0, 2.10.1 task Construct.
22562 // event-handle is a variable of the omp_event_handle_t type.
22563 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22564 if (!Ref) {
22565 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22566 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22567 return nullptr;
22568 }
22569 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22570 if (!VD) {
22571 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22572 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22573 return nullptr;
22574 }
22575 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
22576 VD->getType()) ||
22577 VD->getType().isConstant(Context)) {
22578 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22579 << "omp_event_handle_t" << 1 << VD->getType()
22580 << Evt->getSourceRange();
22581 return nullptr;
22582 }
22583 // OpenMP 5.0, 2.10.1 task Construct
22584 // [detach clause]... The event-handle will be considered as if it was
22585 // specified on a firstprivate clause.
22586 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
22587 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22588 DVar.RefExpr) {
22589 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
22590 << getOpenMPClauseName(DVar.CKind)
22591 << getOpenMPClauseName(OMPC_firstprivate);
22592 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
22593 return nullptr;
22594 }
22595 }
22596
22597 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
22598}
22599
22600OMPClause *Sema::ActOnOpenMPDistScheduleClause(
22601 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
22602 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
22603 SourceLocation EndLoc) {
22604 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
22605 std::string Values;
22606 Values += "'";
22607 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
22608 Values += "'";
22609 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22610 << Values << getOpenMPClauseName(OMPC_dist_schedule);
22611 return nullptr;
22612 }
22613 Expr *ValExpr = ChunkSize;
22614 Stmt *HelperValStmt = nullptr;
22615 if (ChunkSize) {
22616 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
22617 !ChunkSize->isInstantiationDependent() &&
22618 !ChunkSize->containsUnexpandedParameterPack()) {
22619 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
22620 ExprResult Val =
22621 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
22622 if (Val.isInvalid())
22623 return nullptr;
22624
22625 ValExpr = Val.get();
22626
22627 // OpenMP [2.7.1, Restrictions]
22628 // chunk_size must be a loop invariant integer expression with a positive
22629 // value.
22630 if (Optional<llvm::APSInt> Result =
22631 ValExpr->getIntegerConstantExpr(Context)) {
22632 if (Result->isSigned() && !Result->isStrictlyPositive()) {
22633 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22634 << "dist_schedule" << ChunkSize->getSourceRange();
22635 return nullptr;
22636 }
22637 } else if (getOpenMPCaptureRegionForClause(
22638 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
22639 LangOpts.OpenMP) != OMPD_unknown &&
22640 !CurContext->isDependentContext()) {
22641 ValExpr = MakeFullExpr(ValExpr).get();
22642 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22643 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22644 HelperValStmt = buildPreInits(Context, Captures);
22645 }
22646 }
22647 }
22648
22649 return new (Context)
22650 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
22651 Kind, ValExpr, HelperValStmt);
22652}
22653
22654OMPClause *Sema::ActOnOpenMPDefaultmapClause(
22655 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
22656 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
22657 SourceLocation KindLoc, SourceLocation EndLoc) {
22658 if (getLangOpts().OpenMP < 50) {
22659 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22660 Kind != OMPC_DEFAULTMAP_scalar) {
22661 std::string Value;
22662 SourceLocation Loc;
22663 Value += "'";
22664 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22665 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22666 OMPC_DEFAULTMAP_MODIFIER_tofrom);
22667 Loc = MLoc;
22668 } else {
22669 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22670 OMPC_DEFAULTMAP_scalar);
22671 Loc = KindLoc;
22672 }
22673 Value += "'";
22674 Diag(Loc, diag::err_omp_unexpected_clause_value)
22675 << Value << getOpenMPClauseName(OMPC_defaultmap);
22676 return nullptr;
22677 }
22678 } else {
22679 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
22680 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
22681 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
22682 if (!isDefaultmapKind || !isDefaultmapModifier) {
22683 StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
22684 if (LangOpts.OpenMP == 50) {
22685 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
22686 "'firstprivate', 'none', 'default'";
22687 if (!isDefaultmapKind && isDefaultmapModifier) {
22688 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22689 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22690 } else if (isDefaultmapKind && !isDefaultmapModifier) {
22691 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22692 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22693 } else {
22694 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22695 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22696 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22697 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22698 }
22699 } else {
22700 StringRef ModifierValue =
22701 "'alloc', 'from', 'to', 'tofrom', "
22702 "'firstprivate', 'none', 'default', 'present'";
22703 if (!isDefaultmapKind && isDefaultmapModifier) {
22704 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22705 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22706 } else if (isDefaultmapKind && !isDefaultmapModifier) {
22707 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22708 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22709 } else {
22710 Diag(MLoc, diag::err_omp_unexpected_clause_value)
22711 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22712 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22713 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22714 }
22715 }
22716 return nullptr;
22717 }
22718
22719 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22720 // At most one defaultmap clause for each category can appear on the
22721 // directive.
22722 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
22723 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22724 return nullptr;
22725 }
22726 }
22727 if (Kind == OMPC_DEFAULTMAP_unknown) {
22728 // Variable category is not specified - mark all categories.
22729 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22730 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22731 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22732 } else {
22733 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
22734 }
22735
22736 return new (Context)
22737 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
22738}
22739
22740bool Sema::ActOnStartOpenMPDeclareTargetContext(
22741 DeclareTargetContextInfo &DTCI) {
22742 DeclContext *CurLexicalContext = getCurLexicalContext();
22743 if (!CurLexicalContext->isFileContext() &&
22744 !CurLexicalContext->isExternCContext() &&
22745 !CurLexicalContext->isExternCXXContext() &&
22746 !isa<CXXRecordDecl>(CurLexicalContext) &&
22747 !isa<ClassTemplateDecl>(CurLexicalContext) &&
22748 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22749 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22750 Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22751 return false;
22752 }
22753 DeclareTargetNesting.push_back(DTCI);
22754 return true;
22755}
22756
22757const Sema::DeclareTargetContextInfo
22758Sema::ActOnOpenMPEndDeclareTargetDirective() {
22759 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", 22760, __extension__ __PRETTY_FUNCTION__
))
22760 "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", 22760, __extension__ __PRETTY_FUNCTION__
))
;
22761 return DeclareTargetNesting.pop_back_val();
22762}
22763
22764void Sema::ActOnFinishedOpenMPDeclareTargetContext(
22765 DeclareTargetContextInfo &DTCI) {
22766 for (auto &It : DTCI.ExplicitlyMapped)
22767 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
22768}
22769
22770void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
22771 if (DeclareTargetNesting.empty())
22772 return;
22773 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22774 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
22775 << getOpenMPDirectiveName(DTCI.Kind);
22776}
22777
22778NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
22779 CXXScopeSpec &ScopeSpec,
22780 const DeclarationNameInfo &Id) {
22781 LookupResult Lookup(*this, Id, LookupOrdinaryName);
22782 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
22783
22784 if (Lookup.isAmbiguous())
22785 return nullptr;
22786 Lookup.suppressDiagnostics();
22787
22788 if (!Lookup.isSingleResult()) {
22789 VarOrFuncDeclFilterCCC CCC(*this);
22790 if (TypoCorrection Corrected =
22791 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
22792 CTK_ErrorRecovery)) {
22793 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
22794 << Id.getName());
22795 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
22796 return nullptr;
22797 }
22798
22799 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
22800 return nullptr;
22801 }
22802
22803 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
22804 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
22805 !isa<FunctionTemplateDecl>(ND)) {
22806 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
22807 return nullptr;
22808 }
22809 return ND;
22810}
22811
22812void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
22813 OMPDeclareTargetDeclAttr::MapTypeTy MT,
22814 DeclareTargetContextInfo &DTCI) {
22815 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", 22817, __extension__ __PRETTY_FUNCTION__
))
22816 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", 22817, __extension__ __PRETTY_FUNCTION__
))
22817 "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", 22817, __extension__ __PRETTY_FUNCTION__
))
;
22818
22819 // Diagnose marking after use as it may lead to incorrect diagnosis and
22820 // codegen.
22821 if (LangOpts.OpenMP >= 50 &&
22822 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
22823 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
22824
22825 // Explicit declare target lists have precedence.
22826 const unsigned Level = -1;
22827
22828 auto *VD = cast<ValueDecl>(ND);
22829 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22830 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22831 if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
22832 (*ActiveAttr)->getLevel() == Level) {
22833 Diag(Loc, diag::err_omp_device_type_mismatch)
22834 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22835 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22836 (*ActiveAttr)->getDevType());
22837 return;
22838 }
22839 if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
22840 (*ActiveAttr)->getLevel() == Level) {
22841 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22842 return;
22843 }
22844
22845 if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
22846 return;
22847
22848 Expr *IndirectE = nullptr;
22849 bool IsIndirect = false;
22850 if (DTCI.Indirect) {
22851 IndirectE = *DTCI.Indirect;
22852 if (!IndirectE)
22853 IsIndirect = true;
22854 }
22855 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22856 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
22857 SourceRange(Loc, Loc));
22858 ND->addAttr(A);
22859 if (ASTMutationListener *ML = Context.getASTMutationListener())
22860 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22861 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22862}
22863
22864static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
22865 Sema &SemaRef, Decl *D) {
22866 if (!D || !isa<VarDecl>(D))
22867 return;
22868 auto *VD = cast<VarDecl>(D);
22869 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
22870 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22871 if (SemaRef.LangOpts.OpenMP >= 50 &&
22872 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22873 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22874 VD->hasGlobalStorage()) {
22875 if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
22876 *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
22877 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22878 // If a lambda declaration and definition appears between a
22879 // declare target directive and the matching end declare target
22880 // directive, all variables that are captured by the lambda
22881 // expression must also appear in a to clause.
22882 SemaRef.Diag(VD->getLocation(),
22883 diag::err_omp_lambda_capture_in_declare_target_not_to);
22884 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22885 << VD << 0 << SR;
22886 return;
22887 }
22888 }
22889 if (MapTy)
22890 return;
22891 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22892 SemaRef.Diag(SL, diag::note_used_here) << SR;
22893}
22894
22895static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
22896 Sema &SemaRef, DSAStackTy *Stack,
22897 ValueDecl *VD) {
22898 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22899 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
22900 /*FullCheck=*/false);
22901}
22902
22903void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
22904 SourceLocation IdLoc) {
22905 if (!D || D->isInvalidDecl())
22906 return;
22907 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
22908 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
22909 if (auto *VD = dyn_cast<VarDecl>(D)) {
22910 // Only global variables can be marked as declare target.
22911 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22912 !VD->isStaticDataMember())
22913 return;
22914 // 2.10.6: threadprivate variable cannot appear in a declare target
22915 // directive.
22916 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
22917 Diag(SL, diag::err_omp_threadprivate_in_target);
22918 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
22919 return;
22920 }
22921 }
22922 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22923 D = FTD->getTemplatedDecl();
22924 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
22925 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
22926 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22927 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22928 Diag(IdLoc, diag::err_omp_function_in_link_clause);
22929 Diag(FD->getLocation(), diag::note_defined_here) << FD;
22930 return;
22931 }
22932 }
22933 if (auto *VD = dyn_cast<ValueDecl>(D)) {
22934 // Problem if any with var declared with incomplete type will be reported
22935 // as normal, so no need to check it here.
22936 if ((E || !VD->getType()->isIncompleteType()) &&
22937 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
22938 return;
22939 if (!E && isInOpenMPDeclareTargetContext()) {
22940 // Checking declaration inside declare target region.
22941 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22942 isa<FunctionTemplateDecl>(D)) {
22943 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22944 OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22945 unsigned Level = DeclareTargetNesting.size();
22946 if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
22947 return;
22948 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22949 Expr *IndirectE = nullptr;
22950 bool IsIndirect = false;
22951 if (DTCI.Indirect) {
22952 IndirectE = *DTCI.Indirect;
22953 if (!IndirectE)
22954 IsIndirect = true;
22955 }
22956 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22957 Context,
22958 getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
22959 : OMPDeclareTargetDeclAttr::MT_To,
22960 DTCI.DT, IndirectE, IsIndirect, Level,
22961 SourceRange(DTCI.Loc, DTCI.Loc));
22962 D->addAttr(A);
22963 if (ASTMutationListener *ML = Context.getASTMutationListener())
22964 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22965 }
22966 return;
22967 }
22968 }
22969 if (!E)
22970 return;
22971 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
22972}
22973
22974OMPClause *Sema::ActOnOpenMPToClause(
22975 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22976 ArrayRef<SourceLocation> MotionModifiersLoc,
22977 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22978 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22979 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22980 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22981 OMPC_MOTION_MODIFIER_unknown};
22982 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22983
22984 // Process motion-modifiers, flag errors for duplicate modifiers.
22985 unsigned Count = 0;
22986 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22987 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22988 llvm::is_contained(Modifiers, MotionModifiers[I])) {
22989 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22990 continue;
22991 }
22992 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", 22993, __extension__ __PRETTY_FUNCTION__
))
22993 "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", 22993, __extension__ __PRETTY_FUNCTION__
))
;
22994 Modifiers[Count] = MotionModifiers[I];
22995 ModifiersLoc[Count] = MotionModifiersLoc[I];
22996 ++Count;
22997 }
22998
22999 MappableVarListInfo MVLI(VarList);
23000 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
23001 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23002 if (MVLI.ProcessedVarList.empty())
23003 return nullptr;
23004
23005 return OMPToClause::Create(
23006 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23007 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23008 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23009}
23010
23011OMPClause *Sema::ActOnOpenMPFromClause(
23012 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23013 ArrayRef<SourceLocation> MotionModifiersLoc,
23014 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23015 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23016 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23017 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23018 OMPC_MOTION_MODIFIER_unknown};
23019 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23020
23021 // Process motion-modifiers, flag errors for duplicate modifiers.
23022 unsigned Count = 0;
23023 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23024 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23025 llvm::is_contained(Modifiers, MotionModifiers[I])) {
23026 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23027 continue;
23028 }
23029 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", 23030, __extension__ __PRETTY_FUNCTION__
))
23030 "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", 23030, __extension__ __PRETTY_FUNCTION__
))
;
23031 Modifiers[Count] = MotionModifiers[I];
23032 ModifiersLoc[Count] = MotionModifiersLoc[I];
23033 ++Count;
23034 }
23035
23036 MappableVarListInfo MVLI(VarList);
23037 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
23038 MapperIdScopeSpec, MapperId, UnresolvedMappers);
23039 if (MVLI.ProcessedVarList.empty())
23040 return nullptr;
23041
23042 return OMPFromClause::Create(
23043 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23044 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23045 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23046}
23047
23048OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23049 const OMPVarListLocTy &Locs) {
23050 MappableVarListInfo MVLI(VarList);
23051 SmallVector<Expr *, 8> PrivateCopies;
23052 SmallVector<Expr *, 8> Inits;
23053
23054 for (Expr *RefExpr : VarList) {
23055 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", 23055, __extension__ __PRETTY_FUNCTION__
))
;
23056 SourceLocation ELoc;
23057 SourceRange ERange;
23058 Expr *SimpleRefExpr = RefExpr;
23059 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23060 if (Res.second) {
23061 // It will be analyzed later.
23062 MVLI.ProcessedVarList.push_back(RefExpr);
23063 PrivateCopies.push_back(nullptr);
23064 Inits.push_back(nullptr);
23065 }
23066 ValueDecl *D = Res.first;
23067 if (!D)
23068 continue;
23069
23070 QualType Type = D->getType();
23071 Type = Type.getNonReferenceType().getUnqualifiedType();
23072
23073 auto *VD = dyn_cast<VarDecl>(D);
23074
23075 // Item should be a pointer or reference to pointer.
23076 if (!Type->isPointerType()) {
23077 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23078 << 0 << RefExpr->getSourceRange();
23079 continue;
23080 }
23081
23082 // Build the private variable and the expression that refers to it.
23083 auto VDPrivate =
23084 buildVarDecl(*this, ELoc, Type, D->getName(),
23085 D->hasAttrs() ? &D->getAttrs() : nullptr,
23086 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23087 if (VDPrivate->isInvalidDecl())
23088 continue;
23089
23090 CurContext->addDecl(VDPrivate);
23091 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23092 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23093
23094 // Add temporary variable to initialize the private copy of the pointer.
23095 VarDecl *VDInit =
23096 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23097 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23098 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23099 AddInitializerToDecl(VDPrivate,
23100 DefaultLvalueConversion(VDInitRefExpr).get(),
23101 /*DirectInit=*/false);
23102
23103 // If required, build a capture to implement the privatization initialized
23104 // with the current list item value.
23105 DeclRefExpr *Ref = nullptr;
23106 if (!VD)
23107 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23108 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23109 PrivateCopies.push_back(VDPrivateRefExpr);
23110 Inits.push_back(VDInitRefExpr);
23111
23112 // We need to add a data sharing attribute for this variable to make sure it
23113 // is correctly captured. A variable that shows up in a use_device_ptr has
23114 // similar properties of a first private variable.
23115 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23116
23117 // Create a mappable component for the list item. List items in this clause
23118 // only need a component.
23119 MVLI.VarBaseDeclarations.push_back(D);
23120 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23121 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23122 /*IsNonContiguous=*/false);
23123 }
23124
23125 if (MVLI.ProcessedVarList.empty())
23126 return nullptr;
23127
23128 return OMPUseDevicePtrClause::Create(
23129 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23130 MVLI.VarBaseDeclarations, MVLI.VarComponents);
23131}
23132
23133OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23134 const OMPVarListLocTy &Locs) {
23135 MappableVarListInfo MVLI(VarList);
23136
23137 for (Expr *RefExpr : VarList) {
23138 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", 23138, __extension__ __PRETTY_FUNCTION__
))
;
23139 SourceLocation ELoc;
23140 SourceRange ERange;
23141 Expr *SimpleRefExpr = RefExpr;
23142 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23143 /*AllowArraySection=*/true);
23144 if (Res.second) {
23145 // It will be analyzed later.
23146 MVLI.ProcessedVarList.push_back(RefExpr);
23147 }
23148 ValueDecl *D = Res.first;
23149 if (!D)
23150 continue;
23151 auto *VD = dyn_cast<VarDecl>(D);
23152
23153 // If required, build a capture to implement the privatization initialized
23154 // with the current list item value.
23155 DeclRefExpr *Ref = nullptr;
23156 if (!VD)
23157 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23158 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23159
23160 // We need to add a data sharing attribute for this variable to make sure it
23161 // is correctly captured. A variable that shows up in a use_device_addr has
23162 // similar properties of a first private variable.
23163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23164
23165 // Create a mappable component for the list item. List items in this clause
23166 // only need a component.
23167 MVLI.VarBaseDeclarations.push_back(D);
23168 MVLI.VarComponents.emplace_back();
23169 Expr *Component = SimpleRefExpr;
23170 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23171 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23172 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23173 MVLI.VarComponents.back().emplace_back(Component, D,
23174 /*IsNonContiguous=*/false);
23175 }
23176
23177 if (MVLI.ProcessedVarList.empty())
23178 return nullptr;
23179
23180 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23181 MVLI.VarBaseDeclarations,
23182 MVLI.VarComponents);
23183}
23184
23185OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23186 const OMPVarListLocTy &Locs) {
23187 MappableVarListInfo MVLI(VarList);
23188 for (Expr *RefExpr : VarList) {
23189 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", 23189, __extension__ __PRETTY_FUNCTION__
))
;
23190 SourceLocation ELoc;
23191 SourceRange ERange;
23192 Expr *SimpleRefExpr = RefExpr;
23193 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23194 if (Res.second) {
23195 // It will be analyzed later.
23196 MVLI.ProcessedVarList.push_back(RefExpr);
23197 }
23198 ValueDecl *D = Res.first;
23199 if (!D)
23200 continue;
23201
23202 QualType Type = D->getType();
23203 // item should be a pointer or array or reference to pointer or array
23204 if (!Type.getNonReferenceType()->isPointerType() &&
23205 !Type.getNonReferenceType()->isArrayType()) {
23206 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23207 << 0 << RefExpr->getSourceRange();
23208 continue;
23209 }
23210
23211 // Check if the declaration in the clause does not show up in any data
23212 // sharing attribute.
23213 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
23214 if (isOpenMPPrivate(DVar.CKind)) {
23215 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23216 << getOpenMPClauseName(DVar.CKind)
23217 << getOpenMPClauseName(OMPC_is_device_ptr)
23218 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
23219 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
23220 continue;
23221 }
23222
23223 const Expr *ConflictExpr;
23224 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
23225 D, /*CurrentRegionOnly=*/true,
23226 [&ConflictExpr](
23227 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23228 OpenMPClauseKind) -> bool {
23229 ConflictExpr = R.front().getAssociatedExpression();
23230 return true;
23231 })) {
23232 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23233 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23234 << ConflictExpr->getSourceRange();
23235 continue;
23236 }
23237
23238 // Store the components in the stack so that they can be used to check
23239 // against other clauses later on.
23240 OMPClauseMappableExprCommon::MappableComponent MC(
23241 SimpleRefExpr, D, /*IsNonContiguous=*/false);
23242 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
23243 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23244
23245 // Record the expression we've just processed.
23246 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23247
23248 // Create a mappable component for the list item. List items in this clause
23249 // only need a component. We use a null declaration to signal fields in
23250 // 'this'.
23251 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", 23253, __extension__ __PRETTY_FUNCTION__
))
23252 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", 23253, __extension__ __PRETTY_FUNCTION__
))
23253 "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", 23253, __extension__ __PRETTY_FUNCTION__
))
;
23254 MVLI.VarBaseDeclarations.push_back(
23255 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23256 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23257 MVLI.VarComponents.back().push_back(MC);
23258 }
23259
23260 if (MVLI.ProcessedVarList.empty())
23261 return nullptr;
23262
23263 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23264 MVLI.VarBaseDeclarations,
23265 MVLI.VarComponents);
23266}
23267
23268OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23269 const OMPVarListLocTy &Locs) {
23270 MappableVarListInfo MVLI(VarList);
23271 for (Expr *RefExpr : VarList) {
23272 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", 23272, __extension__ __PRETTY_FUNCTION__
))
;
23273 SourceLocation ELoc;
23274 SourceRange ERange;
23275 Expr *SimpleRefExpr = RefExpr;
23276 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23277 /*AllowArraySection=*/true);
23278 if (Res.second) {
23279 // It will be analyzed later.
23280 MVLI.ProcessedVarList.push_back(RefExpr);
23281 }
23282 ValueDecl *D = Res.first;
23283 if (!D)
23284 continue;
23285
23286 // Check if the declaration in the clause does not show up in any data
23287 // sharing attribute.
23288 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
23289 if (isOpenMPPrivate(DVar.CKind)) {
23290 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23291 << getOpenMPClauseName(DVar.CKind)
23292 << getOpenMPClauseName(OMPC_has_device_addr)
23293 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
23294 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
23295 continue;
23296 }
23297
23298 const Expr *ConflictExpr;
23299 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
23300 D, /*CurrentRegionOnly=*/true,
23301 [&ConflictExpr](
23302 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23303 OpenMPClauseKind) -> bool {
23304 ConflictExpr = R.front().getAssociatedExpression();
23305 return true;
23306 })) {
23307 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23308 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23309 << ConflictExpr->getSourceRange();
23310 continue;
23311 }
23312
23313 // Store the components in the stack so that they can be used to check
23314 // against other clauses later on.
23315 Expr *Component = SimpleRefExpr;
23316 auto *VD = dyn_cast<VarDecl>(D);
23317 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23318 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23319 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23320 OMPClauseMappableExprCommon::MappableComponent MC(
23321 Component, D, /*IsNonContiguous=*/false);
23322 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
23323 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23324
23325 // Record the expression we've just processed.
23326 if (!VD && !CurContext->isDependentContext()) {
23327 DeclRefExpr *Ref =
23328 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23329 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", 23329, __extension__ __PRETTY_FUNCTION__
))
;
23330 MVLI.ProcessedVarList.push_back(Ref);
23331 } else
23332 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23333
23334 // Create a mappable component for the list item. List items in this clause
23335 // only need a component. We use a null declaration to signal fields in
23336 // 'this'.
23337 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", 23339, __extension__ __PRETTY_FUNCTION__
))
23338 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", 23339, __extension__ __PRETTY_FUNCTION__
))
23339 "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", 23339, __extension__ __PRETTY_FUNCTION__
))
;
23340 MVLI.VarBaseDeclarations.push_back(
23341 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23342 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23343 MVLI.VarComponents.back().push_back(MC);
23344 }
23345
23346 if (MVLI.ProcessedVarList.empty())
23347 return nullptr;
23348
23349 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23350 MVLI.VarBaseDeclarations,
23351 MVLI.VarComponents);
23352}
23353
23354OMPClause *Sema::ActOnOpenMPAllocateClause(
23355 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23356 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23357 if (Allocator) {
23358 // OpenMP [2.11.4 allocate Clause, Description]
23359 // allocator is an expression of omp_allocator_handle_t type.
23360 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
23361 return nullptr;
23362
23363 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23364 if (AllocatorRes.isInvalid())
23365 return nullptr;
23366 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23367 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
23368 Sema::AA_Initializing,
23369 /*AllowExplicit=*/true);
23370 if (AllocatorRes.isInvalid())
23371 return nullptr;
23372 Allocator = AllocatorRes.get();
23373 } else {
23374 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23375 // allocate clauses that appear on a target construct or on constructs in a
23376 // target region must specify an allocator expression unless a requires
23377 // directive with the dynamic_allocators clause is present in the same
23378 // compilation unit.
23379 if (LangOpts.OpenMPIsDevice &&
23380 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23381 targetDiag(StartLoc, diag::err_expected_allocator_expression);
23382 }
23383 // Analyze and build list of variables.
23384 SmallVector<Expr *, 8> Vars;
23385 for (Expr *RefExpr : VarList) {
23386 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", 23386, __extension__ __PRETTY_FUNCTION__
))
;
23387 SourceLocation ELoc;
23388 SourceRange ERange;
23389 Expr *SimpleRefExpr = RefExpr;
23390 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23391 if (Res.second) {
23392 // It will be analyzed later.
23393 Vars.push_back(RefExpr);
23394 }
23395 ValueDecl *D = Res.first;
23396 if (!D)
23397 continue;
23398
23399 auto *VD = dyn_cast<VarDecl>(D);
23400 DeclRefExpr *Ref = nullptr;
23401 if (!VD && !CurContext->isDependentContext())
23402 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23403 Vars.push_back((VD || CurContext->isDependentContext())
23404 ? RefExpr->IgnoreParens()
23405 : Ref);
23406 }
23407
23408 if (Vars.empty())
23409 return nullptr;
23410
23411 if (Allocator)
23412 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
23413 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23414 ColonLoc, EndLoc, Vars);
23415}
23416
23417OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23418 SourceLocation StartLoc,
23419 SourceLocation LParenLoc,
23420 SourceLocation EndLoc) {
23421 SmallVector<Expr *, 8> Vars;
23422 for (Expr *RefExpr : VarList) {
23423 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", 23423, __extension__ __PRETTY_FUNCTION__
))
;
23424 SourceLocation ELoc;
23425 SourceRange ERange;
23426 Expr *SimpleRefExpr = RefExpr;
23427 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23428 if (Res.second)
23429 // It will be analyzed later.
23430 Vars.push_back(RefExpr);
23431 ValueDecl *D = Res.first;
23432 if (!D)
23433 continue;
23434
23435 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23436 // A list-item cannot appear in more than one nontemporal clause.
23437 if (const Expr *PrevRef =
23438 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
23439 Diag(ELoc, diag::err_omp_used_in_clause_twice)
23440 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23441 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23442 << getOpenMPClauseName(OMPC_nontemporal);
23443 continue;
23444 }
23445
23446 Vars.push_back(RefExpr);
23447 }
23448
23449 if (Vars.empty())
23450 return nullptr;
23451
23452 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23453 Vars);
23454}
23455
23456OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
23457 SourceLocation StartLoc,
23458 SourceLocation LParenLoc,
23459 SourceLocation EndLoc) {
23460 SmallVector<Expr *, 8> Vars;
23461 for (Expr *RefExpr : VarList) {
23462 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", 23462, __extension__ __PRETTY_FUNCTION__
))
;
23463 SourceLocation ELoc;
23464 SourceRange ERange;
23465 Expr *SimpleRefExpr = RefExpr;
23466 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23467 /*AllowArraySection=*/true);
23468 if (Res.second)
23469 // It will be analyzed later.
23470 Vars.push_back(RefExpr);
23471 ValueDecl *D = Res.first;
23472 if (!D)
23473 continue;
23474
23475 const DSAStackTy::DSAVarData DVar =
23476 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
23477 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23478 // A list item that appears in the inclusive or exclusive clause must appear
23479 // in a reduction clause with the inscan modifier on the enclosing
23480 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23481 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23482 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23483 << RefExpr->getSourceRange();
23484
23485 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
23486 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
23487 Vars.push_back(RefExpr);
23488 }
23489
23490 if (Vars.empty())
23491 return nullptr;
23492
23493 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23494}
23495
23496OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
23497 SourceLocation StartLoc,
23498 SourceLocation LParenLoc,
23499 SourceLocation EndLoc) {
23500 SmallVector<Expr *, 8> Vars;
23501 for (Expr *RefExpr : VarList) {
23502 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", 23502, __extension__ __PRETTY_FUNCTION__
))
;
23503 SourceLocation ELoc;
23504 SourceRange ERange;
23505 Expr *SimpleRefExpr = RefExpr;
23506 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23507 /*AllowArraySection=*/true);
23508 if (Res.second)
23509 // It will be analyzed later.
23510 Vars.push_back(RefExpr);
23511 ValueDecl *D = Res.first;
23512 if (!D)
23513 continue;
23514
23515 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
23516 DSAStackTy::DSAVarData DVar;
23517 if (ParentDirective != OMPD_unknown)
23518 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
23519 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23520 // A list item that appears in the inclusive or exclusive clause must appear
23521 // in a reduction clause with the inscan modifier on the enclosing
23522 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23523 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23524 DVar.Modifier != OMPC_REDUCTION_inscan) {
23525 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23526 << RefExpr->getSourceRange();
23527 } else {
23528 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
23529 }
23530 Vars.push_back(RefExpr);
23531 }
23532
23533 if (Vars.empty())
23534 return nullptr;
23535
23536 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23537}
23538
23539/// Tries to find omp_alloctrait_t type.
23540static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
23541 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23542 if (!OMPAlloctraitT.isNull())
23543 return true;
23544 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
23545 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
23546 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23547 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
23548 return false;
23549 }
23550 Stack->setOMPAlloctraitT(PT.get());
23551 return true;
23552}
23553
23554OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
23555 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
23556 ArrayRef<UsesAllocatorsData> Data) {
23557 // OpenMP [2.12.5, target Construct]
23558 // allocator is an identifier of omp_allocator_handle_t type.
23559 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
23560 return nullptr;
23561 // OpenMP [2.12.5, target Construct]
23562 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23563 if (llvm::any_of(
23564 Data,
23565 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
23566 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
23567 return nullptr;
23568 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
23569 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23570 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
23571 StringRef Allocator =
23572 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23573 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
23574 PredefinedAllocators.insert(LookupSingleName(
23575 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
23576 }
23577
23578 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
23579 for (const UsesAllocatorsData &D : Data) {
23580 Expr *AllocatorExpr = nullptr;
23581 // Check allocator expression.
23582 if (D.Allocator->isTypeDependent()) {
23583 AllocatorExpr = D.Allocator;
23584 } else {
23585 // Traits were specified - need to assign new allocator to the specified
23586 // allocator, so it must be an lvalue.
23587 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
23588 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23589 bool IsPredefinedAllocator = false;
23590 if (DRE)
23591 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
23592 if (!DRE ||
23593 !(Context.hasSameUnqualifiedType(
23594 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
23595 Context.typesAreCompatible(AllocatorExpr->getType(),
23596 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
23597 /*CompareUnqualified=*/true)) ||
23598 (!IsPredefinedAllocator &&
23599 (AllocatorExpr->getType().isConstant(Context) ||
23600 !AllocatorExpr->isLValue()))) {
23601 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
23602 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
23603 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
23604 continue;
23605 }
23606 // OpenMP [2.12.5, target Construct]
23607 // Predefined allocators appearing in a uses_allocators clause cannot have
23608 // traits specified.
23609 if (IsPredefinedAllocator && D.AllocatorTraits) {
23610 Diag(D.AllocatorTraits->getExprLoc(),
23611 diag::err_omp_predefined_allocator_with_traits)
23612 << D.AllocatorTraits->getSourceRange();
23613 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
23614 << cast<NamedDecl>(DRE->getDecl())->getName()
23615 << D.Allocator->getSourceRange();
23616 continue;
23617 }
23618 // OpenMP [2.12.5, target Construct]
23619 // Non-predefined allocators appearing in a uses_allocators clause must
23620 // have traits specified.
23621 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
23622 Diag(D.Allocator->getExprLoc(),
23623 diag::err_omp_nonpredefined_allocator_without_traits);
23624 continue;
23625 }
23626 // No allocator traits - just convert it to rvalue.
23627 if (!D.AllocatorTraits)
23628 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
23629 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
23630 DRE->getDecl(),
23631 IsPredefinedAllocator
23632 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23633 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23634 }
23635 Expr *AllocatorTraitsExpr = nullptr;
23636 if (D.AllocatorTraits) {
23637 if (D.AllocatorTraits->isTypeDependent()) {
23638 AllocatorTraitsExpr = D.AllocatorTraits;
23639 } else {
23640 // OpenMP [2.12.5, target Construct]
23641 // Arrays that contain allocator traits that appear in a uses_allocators
23642 // clause must be constant arrays, have constant values and be defined
23643 // in the same scope as the construct in which the clause appears.
23644 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
23645 // Check that traits expr is a constant array.
23646 QualType TraitTy;
23647 if (const ArrayType *Ty =
23648 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
23649 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23650 TraitTy = ConstArrayTy->getElementType();
23651 if (TraitTy.isNull() ||
23652 !(Context.hasSameUnqualifiedType(TraitTy,
23653 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
23654 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
23655 /*CompareUnqualified=*/true))) {
23656 Diag(D.AllocatorTraits->getExprLoc(),
23657 diag::err_omp_expected_array_alloctraits)
23658 << AllocatorTraitsExpr->getType();
23659 continue;
23660 }
23661 // Do not map by default allocator traits if it is a standalone
23662 // variable.
23663 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23664 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
23665 DRE->getDecl(),
23666 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23667 }
23668 }
23669 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
23670 NewD.Allocator = AllocatorExpr;
23671 NewD.AllocatorTraits = AllocatorTraitsExpr;
23672 NewD.LParenLoc = D.LParenLoc;
23673 NewD.RParenLoc = D.RParenLoc;
23674 }
23675 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23676 NewData);
23677}
23678
23679OMPClause *Sema::ActOnOpenMPAffinityClause(
23680 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23681 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
23682 SmallVector<Expr *, 8> Vars;
23683 for (Expr *RefExpr : Locators) {
23684 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", 23684, __extension__ __PRETTY_FUNCTION__
))
;
23685 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23686 // It will be analyzed later.
23687 Vars.push_back(RefExpr);
23688 continue;
23689 }
23690
23691 SourceLocation ELoc = RefExpr->getExprLoc();
23692 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
23693
23694 if (!SimpleExpr->isLValue()) {
23695 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23696 << 1 << 0 << RefExpr->getSourceRange();
23697 continue;
23698 }
23699
23700 ExprResult Res;
23701 {
23702 Sema::TentativeAnalysisScope Trap(*this);
23703 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
23704 }
23705 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
23706 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
23707 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23708 << 1 << 0 << RefExpr->getSourceRange();
23709 continue;
23710 }
23711 Vars.push_back(SimpleExpr);
23712 }
23713
23714 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
23715 EndLoc, Modifier, Vars);
23716}
23717
23718OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
23719 SourceLocation KindLoc,
23720 SourceLocation StartLoc,
23721 SourceLocation LParenLoc,
23722 SourceLocation EndLoc) {
23723 if (Kind == OMPC_BIND_unknown) {
23724 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23725 << getListOfPossibleValues(OMPC_bind, /*First=*/0,
23726 /*Last=*/unsigned(OMPC_BIND_unknown))
23727 << getOpenMPClauseName(OMPC_bind);
23728 return nullptr;
23729 }
23730
23731 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
23732 EndLoc);
23733}