Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 4273, column 5
Value stored to 'ErrorFound' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-08-06-171148-17323-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/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/Frontend/OpenMP/OMPConstants.h"
39#include <set>
40
41using namespace clang;
42using namespace llvm::omp;
43
44//===----------------------------------------------------------------------===//
45// Stack of data-sharing attributes for variables
46//===----------------------------------------------------------------------===//
47
48static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, bool NoDiagnose);
52
53namespace {
54/// Default data sharing attributes, which can be applied to directive.
55enum DefaultDataSharingAttributes {
56 DSA_unspecified = 0, /// Data sharing attribute not specified.
57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
60};
61
62/// Stack for tracking declarations used in OpenMP directives and
63/// clauses and their data-sharing attributes.
64class DSAStackTy {
65public:
66 struct DSAVarData {
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 DSAVarData() = default;
74 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
75 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
76 SourceLocation ImplicitDSALoc, unsigned Modifier)
77 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
78 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
79 };
80 using OperatorOffsetTy =
81 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
82 using DoacrossDependMapTy =
83 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
84 /// Kind of the declaration used in the uses_allocators clauses.
85 enum class UsesAllocatorsDeclKind {
86 /// Predefined allocator
87 PredefinedAllocator,
88 /// User-defined allocator
89 UserDefinedAllocator,
90 /// The declaration that represent allocator trait
91 AllocatorTrait,
92 };
93
94private:
95 struct DSAInfo {
96 OpenMPClauseKind Attributes = OMPC_unknown;
97 unsigned Modifier = 0;
98 /// Pointer to a reference expression and a flag which shows that the
99 /// variable is marked as lastprivate(true) or not (false).
100 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
101 DeclRefExpr *PrivateCopy = nullptr;
102 };
103 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
104 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
105 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
106 using LoopControlVariablesMapTy =
107 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
108 /// Struct that associates a component with the clause kind where they are
109 /// found.
110 struct MappedExprComponentTy {
111 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
112 OpenMPClauseKind Kind = OMPC_unknown;
113 };
114 using MappedExprComponentsTy =
115 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
116 using CriticalsWithHintsTy =
117 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
118 struct ReductionData {
119 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
120 SourceRange ReductionRange;
121 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
122 ReductionData() = default;
123 void set(BinaryOperatorKind BO, SourceRange RR) {
124 ReductionRange = RR;
125 ReductionOp = BO;
126 }
127 void set(const Expr *RefExpr, SourceRange RR) {
128 ReductionRange = RR;
129 ReductionOp = RefExpr;
130 }
131 };
132 using DeclReductionMapTy =
133 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
134 struct DefaultmapInfo {
135 OpenMPDefaultmapClauseModifier ImplicitBehavior =
136 OMPC_DEFAULTMAP_MODIFIER_unknown;
137 SourceLocation SLoc;
138 DefaultmapInfo() = default;
139 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
140 : ImplicitBehavior(M), SLoc(Loc) {}
141 };
142
143 struct SharingMapTy {
144 DeclSAMapTy SharingMap;
145 DeclReductionMapTy ReductionMap;
146 UsedRefMapTy AlignedMap;
147 UsedRefMapTy NontemporalMap;
148 MappedExprComponentsTy MappedExprComponents;
149 LoopControlVariablesMapTy LCVMap;
150 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
151 SourceLocation DefaultAttrLoc;
152 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
153 OpenMPDirectiveKind Directive = OMPD_unknown;
154 DeclarationNameInfo DirectiveName;
155 Scope *CurScope = nullptr;
156 SourceLocation ConstructLoc;
157 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
158 /// get the data (loop counters etc.) about enclosing loop-based construct.
159 /// This data is required during codegen.
160 DoacrossDependMapTy DoacrossDepends;
161 /// First argument (Expr *) contains optional argument of the
162 /// 'ordered' clause, the second one is true if the regions has 'ordered'
163 /// clause, false otherwise.
164 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
165 unsigned AssociatedLoops = 1;
166 bool HasMutipleLoops = false;
167 const Decl *PossiblyLoopCounter = nullptr;
168 bool NowaitRegion = false;
169 bool CancelRegion = false;
170 bool LoopStart = false;
171 bool BodyComplete = false;
172 SourceLocation PrevScanLocation;
173 SourceLocation PrevOrderedLocation;
174 SourceLocation InnerTeamsRegionLoc;
175 /// Reference to the taskgroup task_reduction reference expression.
176 Expr *TaskgroupReductionRef = nullptr;
177 llvm::DenseSet<QualType> MappedClassesQualTypes;
178 SmallVector<Expr *, 4> InnerUsedAllocators;
179 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
180 /// List of globals marked as declare target link in this target region
181 /// (isOpenMPTargetExecutionDirective(Directive) == true).
182 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
183 /// List of decls used in inclusive/exclusive clauses of the scan directive.
184 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
185 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
186 UsesAllocatorsDecls;
187 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
188 Scope *CurScope, SourceLocation Loc)
189 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
190 ConstructLoc(Loc) {}
191 SharingMapTy() = default;
192 };
193
194 using StackTy = SmallVector<SharingMapTy, 4>;
195
196 /// Stack of used declaration and their data-sharing attributes.
197 DeclSAMapTy Threadprivates;
198 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
199 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
200 /// true, if check for DSA must be from parent directive, false, if
201 /// from current directive.
202 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
203 Sema &SemaRef;
204 bool ForceCapturing = false;
205 /// true if all the variables in the target executable directives must be
206 /// captured by reference.
207 bool ForceCaptureByReferenceInTargetExecutable = false;
208 CriticalsWithHintsTy Criticals;
209 unsigned IgnoredStackElements = 0;
210
211 /// Iterators over the stack iterate in order from innermost to outermost
212 /// directive.
213 using const_iterator = StackTy::const_reverse_iterator;
214 const_iterator begin() const {
215 return Stack.empty() ? const_iterator()
216 : Stack.back().first.rbegin() + IgnoredStackElements;
217 }
218 const_iterator end() const {
219 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
220 }
221 using iterator = StackTy::reverse_iterator;
222 iterator begin() {
223 return Stack.empty() ? iterator()
224 : Stack.back().first.rbegin() + IgnoredStackElements;
225 }
226 iterator end() {
227 return Stack.empty() ? iterator() : Stack.back().first.rend();
228 }
229
230 // Convenience operations to get at the elements of the stack.
231
232 bool isStackEmpty() const {
233 return Stack.empty() ||
234 Stack.back().second != CurrentNonCapturingFunctionScope ||
235 Stack.back().first.size() <= IgnoredStackElements;
236 }
237 size_t getStackSize() const {
238 return isStackEmpty() ? 0
239 : Stack.back().first.size() - IgnoredStackElements;
240 }
241
242 SharingMapTy *getTopOfStackOrNull() {
243 size_t Size = getStackSize();
244 if (Size == 0)
245 return nullptr;
246 return &Stack.back().first[Size - 1];
247 }
248 const SharingMapTy *getTopOfStackOrNull() const {
249 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
250 }
251 SharingMapTy &getTopOfStack() {
252 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 252, __PRETTY_FUNCTION__))
;
253 return *getTopOfStackOrNull();
254 }
255 const SharingMapTy &getTopOfStack() const {
256 return const_cast<DSAStackTy&>(*this).getTopOfStack();
257 }
258
259 SharingMapTy *getSecondOnStackOrNull() {
260 size_t Size = getStackSize();
261 if (Size <= 1)
262 return nullptr;
263 return &Stack.back().first[Size - 2];
264 }
265 const SharingMapTy *getSecondOnStackOrNull() const {
266 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
267 }
268
269 /// Get the stack element at a certain level (previously returned by
270 /// \c getNestingLevel).
271 ///
272 /// Note that nesting levels count from outermost to innermost, and this is
273 /// the reverse of our iteration order where new inner levels are pushed at
274 /// the front of the stack.
275 SharingMapTy &getStackElemAtLevel(unsigned Level) {
276 assert(Level < getStackSize() && "no such stack element")((Level < getStackSize() && "no such stack element"
) ? static_cast<void> (0) : __assert_fail ("Level < getStackSize() && \"no such stack element\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 276, __PRETTY_FUNCTION__))
;
277 return Stack.back().first[Level];
278 }
279 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
280 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
281 }
282
283 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
284
285 /// Checks if the variable is a local for OpenMP region.
286 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
287
288 /// Vector of previously declared requires directives
289 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
290 /// omp_allocator_handle_t type.
291 QualType OMPAllocatorHandleT;
292 /// omp_depend_t type.
293 QualType OMPDependT;
294 /// omp_event_handle_t type.
295 QualType OMPEventHandleT;
296 /// omp_alloctrait_t type.
297 QualType OMPAlloctraitT;
298 /// Expression for the predefined allocators.
299 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
300 nullptr};
301 /// Vector of previously encountered target directives
302 SmallVector<SourceLocation, 2> TargetLocations;
303 SourceLocation AtomicLocation;
304
305public:
306 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
307
308 /// Sets omp_allocator_handle_t type.
309 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
310 /// Gets omp_allocator_handle_t type.
311 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
312 /// Sets omp_alloctrait_t type.
313 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
314 /// Gets omp_alloctrait_t type.
315 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
316 /// Sets the given default allocator.
317 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
318 Expr *Allocator) {
319 OMPPredefinedAllocators[AllocatorKind] = Allocator;
320 }
321 /// Returns the specified default allocator.
322 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
323 return OMPPredefinedAllocators[AllocatorKind];
324 }
325 /// Sets omp_depend_t type.
326 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
327 /// Gets omp_depend_t type.
328 QualType getOMPDependT() const { return OMPDependT; }
329
330 /// Sets omp_event_handle_t type.
331 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
332 /// Gets omp_event_handle_t type.
333 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
334
335 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
336 OpenMPClauseKind getClauseParsingMode() const {
337 assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode."
) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 337, __PRETTY_FUNCTION__))
;
338 return ClauseKindMode;
339 }
340 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
341
342 bool isBodyComplete() const {
343 const SharingMapTy *Top = getTopOfStackOrNull();
344 return Top && Top->BodyComplete;
345 }
346 void setBodyComplete() {
347 getTopOfStack().BodyComplete = true;
348 }
349
350 bool isForceVarCapturing() const { return ForceCapturing; }
351 void setForceVarCapturing(bool V) { ForceCapturing = V; }
352
353 void setForceCaptureByReferenceInTargetExecutable(bool V) {
354 ForceCaptureByReferenceInTargetExecutable = V;
355 }
356 bool isForceCaptureByReferenceInTargetExecutable() const {
357 return ForceCaptureByReferenceInTargetExecutable;
358 }
359
360 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
361 Scope *CurScope, SourceLocation Loc) {
362 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 363, __PRETTY_FUNCTION__))
363 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 363, __PRETTY_FUNCTION__))
;
364 if (Stack.empty() ||
365 Stack.back().second != CurrentNonCapturingFunctionScope)
366 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
367 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
368 Stack.back().first.back().DefaultAttrLoc = Loc;
369 }
370
371 void pop() {
372 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 373, __PRETTY_FUNCTION__))
373 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 373, __PRETTY_FUNCTION__))
;
374 assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 375, __PRETTY_FUNCTION__))
375 "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 375, __PRETTY_FUNCTION__))
;
376 Stack.back().first.pop_back();
377 }
378
379 /// RAII object to temporarily leave the scope of a directive when we want to
380 /// logically operate in its parent.
381 class ParentDirectiveScope {
382 DSAStackTy &Self;
383 bool Active;
384 public:
385 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
386 : Self(Self), Active(false) {
387 if (Activate)
388 enable();
389 }
390 ~ParentDirectiveScope() { disable(); }
391 void disable() {
392 if (Active) {
393 --Self.IgnoredStackElements;
394 Active = false;
395 }
396 }
397 void enable() {
398 if (!Active) {
399 ++Self.IgnoredStackElements;
400 Active = true;
401 }
402 }
403 };
404
405 /// Marks that we're started loop parsing.
406 void loopInit() {
407 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 408, __PRETTY_FUNCTION__))
408 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 408, __PRETTY_FUNCTION__))
;
409 getTopOfStack().LoopStart = true;
410 }
411 /// Start capturing of the variables in the loop context.
412 void loopStart() {
413 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 414, __PRETTY_FUNCTION__))
414 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 414, __PRETTY_FUNCTION__))
;
415 getTopOfStack().LoopStart = false;
416 }
417 /// true, if variables are captured, false otherwise.
418 bool isLoopStarted() const {
419 assert(isOpenMPLoopDirective(getCurrentDirective()) &&((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 420, __PRETTY_FUNCTION__))
420 "Expected loop-based directive.")((isOpenMPLoopDirective(getCurrentDirective()) && "Expected loop-based directive."
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(getCurrentDirective()) && \"Expected loop-based directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 420, __PRETTY_FUNCTION__))
;
421 return !getTopOfStack().LoopStart;
422 }
423 /// Marks (or clears) declaration as possibly loop counter.
424 void resetPossibleLoopCounter(const Decl *D = nullptr) {
425 getTopOfStack().PossiblyLoopCounter =
426 D ? D->getCanonicalDecl() : D;
427 }
428 /// Gets the possible loop counter decl.
429 const Decl *getPossiblyLoopCunter() const {
430 return getTopOfStack().PossiblyLoopCounter;
431 }
432 /// Start new OpenMP region stack in new non-capturing function.
433 void pushFunction() {
434 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 435, __PRETTY_FUNCTION__))
435 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 435, __PRETTY_FUNCTION__))
;
436 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
437 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 437, __PRETTY_FUNCTION__))
;
438 CurrentNonCapturingFunctionScope = CurFnScope;
439 }
440 /// Pop region stack for non-capturing function.
441 void popFunction(const FunctionScopeInfo *OldFSI) {
442 assert(!IgnoredStackElements &&((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 443, __PRETTY_FUNCTION__))
443 "cannot change stack while ignoring elements")((!IgnoredStackElements && "cannot change stack while ignoring elements"
) ? static_cast<void> (0) : __assert_fail ("!IgnoredStackElements && \"cannot change stack while ignoring elements\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 443, __PRETTY_FUNCTION__))
;
444 if (!Stack.empty() && Stack.back().second == OldFSI) {
445 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 445, __PRETTY_FUNCTION__))
;
446 Stack.pop_back();
447 }
448 CurrentNonCapturingFunctionScope = nullptr;
449 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
450 if (!isa<CapturingScopeInfo>(FSI)) {
451 CurrentNonCapturingFunctionScope = FSI;
452 break;
453 }
454 }
455 }
456
457 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
458 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
459 }
460 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
461 getCriticalWithHint(const DeclarationNameInfo &Name) const {
462 auto I = Criticals.find(Name.getAsString());
463 if (I != Criticals.end())
464 return I->second;
465 return std::make_pair(nullptr, llvm::APSInt());
466 }
467 /// If 'aligned' declaration for given variable \a D was not seen yet,
468 /// add it and return NULL; otherwise return previous occurrence's expression
469 /// for diagnostics.
470 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
471 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
472 /// add it and return NULL; otherwise return previous occurrence's expression
473 /// for diagnostics.
474 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
475
476 /// Register specified variable as loop control variable.
477 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
478 /// Check if the specified variable is a loop control variable for
479 /// current region.
480 /// \return The index of the loop control variable in the list of associated
481 /// for-loops (from outer to inner).
482 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
483 /// Check if the specified variable is a loop control variable for
484 /// parent region.
485 /// \return The index of the loop control variable in the list of associated
486 /// for-loops (from outer to inner).
487 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
488 /// Check if the specified variable is a loop control variable for
489 /// current region.
490 /// \return The index of the loop control variable in the list of associated
491 /// for-loops (from outer to inner).
492 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
493 unsigned Level) const;
494 /// Get the loop control variable for the I-th loop (or nullptr) in
495 /// parent directive.
496 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
497
498 /// Marks the specified decl \p D as used in scan directive.
499 void markDeclAsUsedInScanDirective(ValueDecl *D) {
500 if (SharingMapTy *Stack = getSecondOnStackOrNull())
501 Stack->UsedInScanDirective.insert(D);
502 }
503
504 /// Checks if the specified declaration was used in the inner scan directive.
505 bool isUsedInScanDirective(ValueDecl *D) const {
506 if (const SharingMapTy *Stack = getTopOfStackOrNull())
507 return Stack->UsedInScanDirective.count(D) > 0;
508 return false;
509 }
510
511 /// Adds explicit data sharing attribute to the specified declaration.
512 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
513 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0);
514
515 /// Adds additional information for the reduction items with the reduction id
516 /// represented as an operator.
517 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
518 BinaryOperatorKind BOK);
519 /// Adds additional information for the reduction items with the reduction id
520 /// represented as reduction identifier.
521 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
522 const Expr *ReductionRef);
523 /// Returns the location and reduction operation from the innermost parent
524 /// region for the given \p D.
525 const DSAVarData
526 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
527 BinaryOperatorKind &BOK,
528 Expr *&TaskgroupDescriptor) const;
529 /// Returns the location and reduction operation from the innermost parent
530 /// region for the given \p D.
531 const DSAVarData
532 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
533 const Expr *&ReductionRef,
534 Expr *&TaskgroupDescriptor) const;
535 /// Return reduction reference expression for the current taskgroup or
536 /// parallel/worksharing directives with task reductions.
537 Expr *getTaskgroupReductionRef() const {
538 assert((getTopOfStack().Directive == OMPD_taskgroup ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
539 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
540 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
541 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
542 "taskgroup reference expression requested for non taskgroup or "(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
543 "parallel/worksharing directive.")(((getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "taskgroup reference expression requested for non taskgroup or "
"parallel/worksharing directive.") ? static_cast<void>
(0) : __assert_fail ("(getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"taskgroup reference expression requested for non taskgroup or \" \"parallel/worksharing directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 543, __PRETTY_FUNCTION__))
;
544 return getTopOfStack().TaskgroupReductionRef;
545 }
546 /// Checks if the given \p VD declaration is actually a taskgroup reduction
547 /// descriptor variable at the \p Level of OpenMP regions.
548 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
549 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
550 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
551 ->getDecl() == VD;
552 }
553
554 /// Returns data sharing attributes from top of the stack for the
555 /// specified declaration.
556 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
557 /// Returns data-sharing attributes for the specified declaration.
558 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
559 /// Returns data-sharing attributes for the specified declaration.
560 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
561 /// Checks if the specified variables has data-sharing attributes which
562 /// match specified \a CPred predicate in any directive which matches \a DPred
563 /// predicate.
564 const DSAVarData
565 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
566 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
567 bool FromParent) const;
568 /// Checks if the specified variables has data-sharing attributes which
569 /// match specified \a CPred predicate in any innermost directive which
570 /// matches \a DPred predicate.
571 const DSAVarData
572 hasInnermostDSA(ValueDecl *D,
573 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
575 bool FromParent) const;
576 /// Checks if the specified variables has explicit data-sharing
577 /// attributes which match specified \a CPred predicate at the specified
578 /// OpenMP region.
579 bool hasExplicitDSA(const ValueDecl *D,
580 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
581 unsigned Level, bool NotLastprivate = false) const;
582
583 /// Returns true if the directive at level \Level matches in the
584 /// specified \a DPred predicate.
585 bool hasExplicitDirective(
586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
587 unsigned Level) const;
588
589 /// Finds a directive which matches specified \a DPred predicate.
590 bool hasDirective(
591 const llvm::function_ref<bool(
592 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
593 DPred,
594 bool FromParent) const;
595
596 /// Returns currently analyzed directive.
597 OpenMPDirectiveKind getCurrentDirective() const {
598 const SharingMapTy *Top = getTopOfStackOrNull();
599 return Top ? Top->Directive : OMPD_unknown;
600 }
601 /// Returns directive kind at specified level.
602 OpenMPDirectiveKind getDirective(unsigned Level) const {
603 assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 603, __PRETTY_FUNCTION__))
;
604 return getStackElemAtLevel(Level).Directive;
605 }
606 /// Returns the capture region at the specified level.
607 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
608 unsigned OpenMPCaptureLevel) const {
609 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
610 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
611 return CaptureRegions[OpenMPCaptureLevel];
612 }
613 /// Returns parent directive.
614 OpenMPDirectiveKind getParentDirective() const {
615 const SharingMapTy *Parent = getSecondOnStackOrNull();
616 return Parent ? Parent->Directive : OMPD_unknown;
617 }
618
619 /// Add requires decl to internal vector
620 void addRequiresDecl(OMPRequiresDecl *RD) {
621 RequiresDecls.push_back(RD);
622 }
623
624 /// Checks if the defined 'requires' directive has specified type of clause.
625 template <typename ClauseType>
626 bool hasRequiresDeclWithClause() const {
627 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
628 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
629 return isa<ClauseType>(C);
630 });
631 });
632 }
633
634 /// Checks for a duplicate clause amongst previously declared requires
635 /// directives
636 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
637 bool IsDuplicate = false;
638 for (OMPClause *CNew : ClauseList) {
639 for (const OMPRequiresDecl *D : RequiresDecls) {
640 for (const OMPClause *CPrev : D->clauselists()) {
641 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
642 SemaRef.Diag(CNew->getBeginLoc(),
643 diag::err_omp_requires_clause_redeclaration)
644 << getOpenMPClauseName(CNew->getClauseKind());
645 SemaRef.Diag(CPrev->getBeginLoc(),
646 diag::note_omp_requires_previous_clause)
647 << getOpenMPClauseName(CPrev->getClauseKind());
648 IsDuplicate = true;
649 }
650 }
651 }
652 }
653 return IsDuplicate;
654 }
655
656 /// Add location of previously encountered target to internal vector
657 void addTargetDirLocation(SourceLocation LocStart) {
658 TargetLocations.push_back(LocStart);
659 }
660
661 /// Add location for the first encountered atomicc directive.
662 void addAtomicDirectiveLoc(SourceLocation Loc) {
663 if (AtomicLocation.isInvalid())
664 AtomicLocation = Loc;
665 }
666
667 /// Returns the location of the first encountered atomic directive in the
668 /// module.
669 SourceLocation getAtomicDirectiveLoc() const {
670 return AtomicLocation;
671 }
672
673 // Return previously encountered target region locations.
674 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
675 return TargetLocations;
676 }
677
678 /// Set default data sharing attribute to none.
679 void setDefaultDSANone(SourceLocation Loc) {
680 getTopOfStack().DefaultAttr = DSA_none;
681 getTopOfStack().DefaultAttrLoc = Loc;
682 }
683 /// Set default data sharing attribute to shared.
684 void setDefaultDSAShared(SourceLocation Loc) {
685 getTopOfStack().DefaultAttr = DSA_shared;
686 getTopOfStack().DefaultAttrLoc = Loc;
687 }
688 /// Set default data sharing attribute to firstprivate.
689 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
690 getTopOfStack().DefaultAttr = DSA_firstprivate;
691 getTopOfStack().DefaultAttrLoc = Loc;
692 }
693 /// Set default data mapping attribute to Modifier:Kind
694 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
695 OpenMPDefaultmapClauseKind Kind,
696 SourceLocation Loc) {
697 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
698 DMI.ImplicitBehavior = M;
699 DMI.SLoc = Loc;
700 }
701 /// Check whether the implicit-behavior has been set in defaultmap
702 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
703 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
704 return getTopOfStack()
705 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
706 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
707 getTopOfStack()
708 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
709 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
710 getTopOfStack()
711 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
712 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
713 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
714 OMPC_DEFAULTMAP_MODIFIER_unknown;
715 }
716
717 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
718 return getStackSize() <= Level ? DSA_unspecified
719 : getStackElemAtLevel(Level).DefaultAttr;
720 }
721 DefaultDataSharingAttributes getDefaultDSA() const {
722 return isStackEmpty() ? DSA_unspecified
723 : getTopOfStack().DefaultAttr;
724 }
725 SourceLocation getDefaultDSALocation() const {
726 return isStackEmpty() ? SourceLocation()
727 : getTopOfStack().DefaultAttrLoc;
728 }
729 OpenMPDefaultmapClauseModifier
730 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
731 return isStackEmpty()
732 ? OMPC_DEFAULTMAP_MODIFIER_unknown
733 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
734 }
735 OpenMPDefaultmapClauseModifier
736 getDefaultmapModifierAtLevel(unsigned Level,
737 OpenMPDefaultmapClauseKind Kind) const {
738 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
739 }
740 bool isDefaultmapCapturedByRef(unsigned Level,
741 OpenMPDefaultmapClauseKind Kind) const {
742 OpenMPDefaultmapClauseModifier M =
743 getDefaultmapModifierAtLevel(Level, Kind);
744 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
745 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
746 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
747 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
748 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
749 }
750 return true;
751 }
752 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
753 OpenMPDefaultmapClauseKind Kind) {
754 switch (Kind) {
755 case OMPC_DEFAULTMAP_scalar:
756 case OMPC_DEFAULTMAP_pointer:
757 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_default);
760 case OMPC_DEFAULTMAP_aggregate:
761 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
762 default:
763 break;
764 }
765 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 765)
;
766 }
767 bool mustBeFirstprivateAtLevel(unsigned Level,
768 OpenMPDefaultmapClauseKind Kind) const {
769 OpenMPDefaultmapClauseModifier M =
770 getDefaultmapModifierAtLevel(Level, Kind);
771 return mustBeFirstprivateBase(M, Kind);
772 }
773 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
774 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
775 return mustBeFirstprivateBase(M, Kind);
776 }
777
778 /// Checks if the specified variable is a threadprivate.
779 bool isThreadPrivate(VarDecl *D) {
780 const DSAVarData DVar = getTopDSA(D, false);
781 return isOpenMPThreadPrivate(DVar.CKind);
782 }
783
784 /// Marks current region as ordered (it has an 'ordered' clause).
785 void setOrderedRegion(bool IsOrdered, const Expr *Param,
786 OMPOrderedClause *Clause) {
787 if (IsOrdered)
788 getTopOfStack().OrderedRegion.emplace(Param, Clause);
789 else
790 getTopOfStack().OrderedRegion.reset();
791 }
792 /// Returns true, if region is ordered (has associated 'ordered' clause),
793 /// false - otherwise.
794 bool isOrderedRegion() const {
795 if (const SharingMapTy *Top = getTopOfStackOrNull())
796 return Top->OrderedRegion.hasValue();
797 return false;
798 }
799 /// Returns optional parameter for the ordered region.
800 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
801 if (const SharingMapTy *Top = getTopOfStackOrNull())
802 if (Top->OrderedRegion.hasValue())
803 return Top->OrderedRegion.getValue();
804 return std::make_pair(nullptr, nullptr);
805 }
806 /// Returns true, if parent region is ordered (has associated
807 /// 'ordered' clause), false - otherwise.
808 bool isParentOrderedRegion() const {
809 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
810 return Parent->OrderedRegion.hasValue();
811 return false;
812 }
813 /// Returns optional parameter for the ordered region.
814 std::pair<const Expr *, OMPOrderedClause *>
815 getParentOrderedRegionParam() const {
816 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
817 if (Parent->OrderedRegion.hasValue())
818 return Parent->OrderedRegion.getValue();
819 return std::make_pair(nullptr, nullptr);
820 }
821 /// Marks current region as nowait (it has a 'nowait' clause).
822 void setNowaitRegion(bool IsNowait = true) {
823 getTopOfStack().NowaitRegion = IsNowait;
824 }
825 /// Returns true, if parent region is nowait (has associated
826 /// 'nowait' clause), false - otherwise.
827 bool isParentNowaitRegion() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 return Parent->NowaitRegion;
830 return false;
831 }
832 /// Marks parent region as cancel region.
833 void setParentCancelRegion(bool Cancel = true) {
834 if (SharingMapTy *Parent = getSecondOnStackOrNull())
835 Parent->CancelRegion |= Cancel;
836 }
837 /// Return true if current region has inner cancel construct.
838 bool isCancelRegion() const {
839 const SharingMapTy *Top = getTopOfStackOrNull();
840 return Top ? Top->CancelRegion : false;
841 }
842
843 /// Mark that parent region already has scan directive.
844 void setParentHasScanDirective(SourceLocation Loc) {
845 if (SharingMapTy *Parent = getSecondOnStackOrNull())
846 Parent->PrevScanLocation = Loc;
847 }
848 /// Return true if current region has inner cancel construct.
849 bool doesParentHasScanDirective() const {
850 const SharingMapTy *Top = getSecondOnStackOrNull();
851 return Top ? Top->PrevScanLocation.isValid() : false;
852 }
853 /// Return true if current region has inner cancel construct.
854 SourceLocation getParentScanDirectiveLoc() const {
855 const SharingMapTy *Top = getSecondOnStackOrNull();
856 return Top ? Top->PrevScanLocation : SourceLocation();
857 }
858 /// Mark that parent region already has ordered directive.
859 void setParentHasOrderedDirective(SourceLocation Loc) {
860 if (SharingMapTy *Parent = getSecondOnStackOrNull())
861 Parent->PrevOrderedLocation = Loc;
862 }
863 /// Return true if current region has inner ordered construct.
864 bool doesParentHasOrderedDirective() const {
865 const SharingMapTy *Top = getSecondOnStackOrNull();
866 return Top ? Top->PrevOrderedLocation.isValid() : false;
867 }
868 /// Returns the location of the previously specified ordered directive.
869 SourceLocation getParentOrderedDirectiveLoc() const {
870 const SharingMapTy *Top = getSecondOnStackOrNull();
871 return Top ? Top->PrevOrderedLocation : SourceLocation();
872 }
873
874 /// Set collapse value for the region.
875 void setAssociatedLoops(unsigned Val) {
876 getTopOfStack().AssociatedLoops = Val;
877 if (Val > 1)
878 getTopOfStack().HasMutipleLoops = true;
879 }
880 /// Return collapse value for region.
881 unsigned getAssociatedLoops() const {
882 const SharingMapTy *Top = getTopOfStackOrNull();
883 return Top ? Top->AssociatedLoops : 0;
884 }
885 /// Returns true if the construct is associated with multiple loops.
886 bool hasMutipleLoops() const {
887 const SharingMapTy *Top = getTopOfStackOrNull();
888 return Top ? Top->HasMutipleLoops : false;
889 }
890
891 /// Marks current target region as one with closely nested teams
892 /// region.
893 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
894 if (SharingMapTy *Parent = getSecondOnStackOrNull())
895 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
896 }
897 /// Returns true, if current region has closely nested teams region.
898 bool hasInnerTeamsRegion() const {
899 return getInnerTeamsRegionLoc().isValid();
900 }
901 /// Returns location of the nested teams region (if any).
902 SourceLocation getInnerTeamsRegionLoc() const {
903 const SharingMapTy *Top = getTopOfStackOrNull();
904 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
905 }
906
907 Scope *getCurScope() const {
908 const SharingMapTy *Top = getTopOfStackOrNull();
909 return Top ? Top->CurScope : nullptr;
910 }
911 SourceLocation getConstructLoc() const {
912 const SharingMapTy *Top = getTopOfStackOrNull();
913 return Top ? Top->ConstructLoc : SourceLocation();
914 }
915
916 /// Do the check specified in \a Check to all component lists and return true
917 /// if any issue is found.
918 bool checkMappableExprComponentListsForDecl(
919 const ValueDecl *VD, bool CurrentRegionOnly,
920 const llvm::function_ref<
921 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
922 OpenMPClauseKind)>
923 Check) const {
924 if (isStackEmpty())
925 return false;
926 auto SI = begin();
927 auto SE = end();
928
929 if (SI == SE)
930 return false;
931
932 if (CurrentRegionOnly)
933 SE = std::next(SI);
934 else
935 std::advance(SI, 1);
936
937 for (; SI != SE; ++SI) {
938 auto MI = SI->MappedExprComponents.find(VD);
939 if (MI != SI->MappedExprComponents.end())
940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
941 MI->second.Components)
942 if (Check(L, MI->second.Kind))
943 return true;
944 }
945 return false;
946 }
947
948 /// Do the check specified in \a Check to all component lists at a given level
949 /// and return true if any issue is found.
950 bool checkMappableExprComponentListsForDeclAtLevel(
951 const ValueDecl *VD, unsigned Level,
952 const llvm::function_ref<
953 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
954 OpenMPClauseKind)>
955 Check) const {
956 if (getStackSize() <= Level)
957 return false;
958
959 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
960 auto MI = StackElem.MappedExprComponents.find(VD);
961 if (MI != StackElem.MappedExprComponents.end())
962 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
963 MI->second.Components)
964 if (Check(L, MI->second.Kind))
965 return true;
966 return false;
967 }
968
969 /// Create a new mappable expression component list associated with a given
970 /// declaration and initialize it with the provided list of components.
971 void addMappableExpressionComponents(
972 const ValueDecl *VD,
973 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
974 OpenMPClauseKind WhereFoundClauseKind) {
975 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
976 // Create new entry and append the new components there.
977 MEC.Components.resize(MEC.Components.size() + 1);
978 MEC.Components.back().append(Components.begin(), Components.end());
979 MEC.Kind = WhereFoundClauseKind;
980 }
981
982 unsigned getNestingLevel() const {
983 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 983, __PRETTY_FUNCTION__))
;
984 return getStackSize() - 1;
985 }
986 void addDoacrossDependClause(OMPDependClause *C,
987 const OperatorOffsetTy &OpsOffs) {
988 SharingMapTy *Parent = getSecondOnStackOrNull();
989 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 989, __PRETTY_FUNCTION__))
;
990 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
991 }
992 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
993 getDoacrossDependClauses() const {
994 const SharingMapTy &StackElem = getTopOfStack();
995 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
996 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
997 return llvm::make_range(Ref.begin(), Ref.end());
998 }
999 return llvm::make_range(StackElem.DoacrossDepends.end(),
1000 StackElem.DoacrossDepends.end());
1001 }
1002
1003 // Store types of classes which have been explicitly mapped
1004 void addMappedClassesQualTypes(QualType QT) {
1005 SharingMapTy &StackElem = getTopOfStack();
1006 StackElem.MappedClassesQualTypes.insert(QT);
1007 }
1008
1009 // Return set of mapped classes types
1010 bool isClassPreviouslyMapped(QualType QT) const {
1011 const SharingMapTy &StackElem = getTopOfStack();
1012 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1013 }
1014
1015 /// Adds global declare target to the parent target region.
1016 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1017 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1019, __PRETTY_FUNCTION__))
1018 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1019, __PRETTY_FUNCTION__))
1019 "Expected declare target link global.")((*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && "Expected declare target link global."
) ? static_cast<void> (0) : __assert_fail ("*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && \"Expected declare target link global.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1019, __PRETTY_FUNCTION__))
;
1020 for (auto &Elem : *this) {
1021 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1022 Elem.DeclareTargetLinkVarDecls.push_back(E);
1023 return;
1024 }
1025 }
1026 }
1027
1028 /// Returns the list of globals with declare target link if current directive
1029 /// is target.
1030 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1031 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1032, __PRETTY_FUNCTION__))
1032 "Expected target executable directive.")((isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
"Expected target executable directive.") ? static_cast<void
> (0) : __assert_fail ("isOpenMPTargetExecutionDirective(getCurrentDirective()) && \"Expected target executable directive.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1032, __PRETTY_FUNCTION__))
;
1033 return getTopOfStack().DeclareTargetLinkVarDecls;
1034 }
1035
1036 /// Adds list of allocators expressions.
1037 void addInnerAllocatorExpr(Expr *E) {
1038 getTopOfStack().InnerUsedAllocators.push_back(E);
1039 }
1040 /// Return list of used allocators.
1041 ArrayRef<Expr *> getInnerAllocators() const {
1042 return getTopOfStack().InnerUsedAllocators;
1043 }
1044 /// Marks the declaration as implicitly firstprivate nin the task-based
1045 /// regions.
1046 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1047 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1048 }
1049 /// Checks if the decl is implicitly firstprivate in the task-based region.
1050 bool isImplicitTaskFirstprivate(Decl *D) const {
1051 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1052 }
1053
1054 /// Marks decl as used in uses_allocators clause as the allocator.
1055 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1056 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1057 }
1058 /// Checks if specified decl is used in uses allocator clause as the
1059 /// allocator.
1060 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1061 const Decl *D) const {
1062 const SharingMapTy &StackElem = getTopOfStack();
1063 auto I = StackElem.UsesAllocatorsDecls.find(D);
1064 if (I == StackElem.UsesAllocatorsDecls.end())
1065 return None;
1066 return I->getSecond();
1067 }
1068 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1069 const SharingMapTy &StackElem = getTopOfStack();
1070 auto I = StackElem.UsesAllocatorsDecls.find(D);
1071 if (I == StackElem.UsesAllocatorsDecls.end())
1072 return None;
1073 return I->getSecond();
1074 }
1075};
1076
1077bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1078 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1079}
1080
1081bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1082 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1083 DKind == OMPD_unknown;
1084}
1085
1086} // namespace
1087
1088static const Expr *getExprAsWritten(const Expr *E) {
1089 if (const auto *FE = dyn_cast<FullExpr>(E))
1090 E = FE->getSubExpr();
1091
1092 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1093 E = MTE->getSubExpr();
1094
1095 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1096 E = Binder->getSubExpr();
1097
1098 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1099 E = ICE->getSubExprAsWritten();
1100 return E->IgnoreParens();
1101}
1102
1103static Expr *getExprAsWritten(Expr *E) {
1104 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1105}
1106
1107static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1108 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1109 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1110 D = ME->getMemberDecl();
1111 const auto *VD = dyn_cast<VarDecl>(D);
1112 const auto *FD = dyn_cast<FieldDecl>(D);
1113 if (VD != nullptr) {
1114 VD = VD->getCanonicalDecl();
1115 D = VD;
1116 } else {
1117 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1117, __PRETTY_FUNCTION__))
;
1118 FD = FD->getCanonicalDecl();
1119 D = FD;
1120 }
1121 return D;
1122}
1123
1124static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1125 return const_cast<ValueDecl *>(
1126 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1127}
1128
1129DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1130 ValueDecl *D) const {
1131 D = getCanonicalDecl(D);
1132 auto *VD = dyn_cast<VarDecl>(D);
1133 const auto *FD = dyn_cast<FieldDecl>(D);
1134 DSAVarData DVar;
1135 if (Iter == end()) {
1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1137 // in a region but not in construct]
1138 // File-scope or namespace-scope variables referenced in called routines
1139 // in the region are shared unless they appear in a threadprivate
1140 // directive.
1141 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1142 DVar.CKind = OMPC_shared;
1143
1144 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1145 // in a region but not in construct]
1146 // Variables with static storage duration that are declared in called
1147 // routines in the region are shared.
1148 if (VD && VD->hasGlobalStorage())
1149 DVar.CKind = OMPC_shared;
1150
1151 // Non-static data members are shared by default.
1152 if (FD)
1153 DVar.CKind = OMPC_shared;
1154
1155 return DVar;
1156 }
1157
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a Construct, C/C++, predetermined, p.1]
1160 // Variables with automatic storage duration that are declared in a scope
1161 // inside the construct are private.
1162 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1163 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1164 DVar.CKind = OMPC_private;
1165 return DVar;
1166 }
1167
1168 DVar.DKind = Iter->Directive;
1169 // Explicitly specified attributes and local variables with predetermined
1170 // attributes.
1171 if (Iter->SharingMap.count(D)) {
1172 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1173 DVar.RefExpr = Data.RefExpr.getPointer();
1174 DVar.PrivateCopy = Data.PrivateCopy;
1175 DVar.CKind = Data.Attributes;
1176 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1177 DVar.Modifier = Data.Modifier;
1178 return DVar;
1179 }
1180
1181 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1182 // in a Construct, C/C++, implicitly determined, p.1]
1183 // In a parallel or task construct, the data-sharing attributes of these
1184 // variables are determined by the default clause, if present.
1185 switch (Iter->DefaultAttr) {
1186 case DSA_shared:
1187 DVar.CKind = OMPC_shared;
1188 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1189 return DVar;
1190 case DSA_none:
1191 return DVar;
1192 case DSA_firstprivate:
1193 if (VD->getStorageDuration() == SD_Static &&
1194 VD->getDeclContext()->isFileContext()) {
1195 DVar.CKind = OMPC_unknown;
1196 } else {
1197 DVar.CKind = OMPC_firstprivate;
1198 }
1199 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1200 return DVar;
1201 case DSA_unspecified:
1202 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1203 // in a Construct, implicitly determined, p.2]
1204 // In a parallel construct, if no default clause is present, these
1205 // variables are shared.
1206 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1207 if ((isOpenMPParallelDirective(DVar.DKind) &&
1208 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1209 isOpenMPTeamsDirective(DVar.DKind)) {
1210 DVar.CKind = OMPC_shared;
1211 return DVar;
1212 }
1213
1214 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1215 // in a Construct, implicitly determined, p.4]
1216 // In a task construct, if no default clause is present, a variable that in
1217 // the enclosing context is determined to be shared by all implicit tasks
1218 // bound to the current team is shared.
1219 if (isOpenMPTaskingDirective(DVar.DKind)) {
1220 DSAVarData DVarTemp;
1221 const_iterator I = Iter, E = end();
1222 do {
1223 ++I;
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1225 // Referenced in a Construct, implicitly determined, p.6]
1226 // In a task construct, if no default clause is present, a variable
1227 // whose data-sharing attribute is not determined by the rules above is
1228 // firstprivate.
1229 DVarTemp = getDSA(I, D);
1230 if (DVarTemp.CKind != OMPC_shared) {
1231 DVar.RefExpr = nullptr;
1232 DVar.CKind = OMPC_firstprivate;
1233 return DVar;
1234 }
1235 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1236 DVar.CKind =
1237 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1238 return DVar;
1239 }
1240 }
1241 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1242 // in a Construct, implicitly determined, p.3]
1243 // For constructs other than task, if no default clause is present, these
1244 // variables inherit their data-sharing attributes from the enclosing
1245 // context.
1246 return getDSA(++Iter, D);
1247}
1248
1249const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1250 const Expr *NewDE) {
1251 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1251, __PRETTY_FUNCTION__))
;
1252 D = getCanonicalDecl(D);
1253 SharingMapTy &StackElem = getTopOfStack();
1254 auto It = StackElem.AlignedMap.find(D);
1255 if (It == StackElem.AlignedMap.end()) {
1256 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1256, __PRETTY_FUNCTION__))
;
1257 StackElem.AlignedMap[D] = NewDE;
1258 return nullptr;
1259 }
1260 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1260, __PRETTY_FUNCTION__))
;
1261 return It->second;
1262}
1263
1264const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1265 const Expr *NewDE) {
1266 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1266, __PRETTY_FUNCTION__))
;
1267 D = getCanonicalDecl(D);
1268 SharingMapTy &StackElem = getTopOfStack();
1269 auto It = StackElem.NontemporalMap.find(D);
1270 if (It == StackElem.NontemporalMap.end()) {
1271 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1271, __PRETTY_FUNCTION__))
;
1272 StackElem.NontemporalMap[D] = NewDE;
1273 return nullptr;
1274 }
1275 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1275, __PRETTY_FUNCTION__))
;
1276 return It->second;
1277}
1278
1279void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1280 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1280, __PRETTY_FUNCTION__))
;
1281 D = getCanonicalDecl(D);
1282 SharingMapTy &StackElem = getTopOfStack();
1283 StackElem.LCVMap.try_emplace(
1284 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1285}
1286
1287const DSAStackTy::LCDeclInfo
1288DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1289 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1289, __PRETTY_FUNCTION__))
;
1290 D = getCanonicalDecl(D);
1291 const SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.LCVMap.find(D);
1293 if (It != StackElem.LCVMap.end())
1294 return It->second;
1295 return {0, nullptr};
1296}
1297
1298const DSAStackTy::LCDeclInfo
1299DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1300 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1300, __PRETTY_FUNCTION__))
;
1301 D = getCanonicalDecl(D);
1302 for (unsigned I = Level + 1; I > 0; --I) {
1303 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1304 auto It = StackElem.LCVMap.find(D);
1305 if (It != StackElem.LCVMap.end())
1306 return It->second;
1307 }
1308 return {0, nullptr};
1309}
1310
1311const DSAStackTy::LCDeclInfo
1312DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1313 const SharingMapTy *Parent = getSecondOnStackOrNull();
1314 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1314, __PRETTY_FUNCTION__))
;
1315 D = getCanonicalDecl(D);
1316 auto It = Parent->LCVMap.find(D);
1317 if (It != Parent->LCVMap.end())
1318 return It->second;
1319 return {0, nullptr};
1320}
1321
1322const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1323 const SharingMapTy *Parent = getSecondOnStackOrNull();
1324 assert(Parent && "Data-sharing attributes stack is empty")((Parent && "Data-sharing attributes stack is empty")
? static_cast<void> (0) : __assert_fail ("Parent && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1324, __PRETTY_FUNCTION__))
;
1325 if (Parent->LCVMap.size() < I)
1326 return nullptr;
1327 for (const auto &Pair : Parent->LCVMap)
1328 if (Pair.second.first == I)
1329 return Pair.first;
1330 return nullptr;
1331}
1332
1333void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1334 DeclRefExpr *PrivateCopy, unsigned Modifier) {
1335 D = getCanonicalDecl(D);
1336 if (A == OMPC_threadprivate) {
1337 DSAInfo &Data = Threadprivates[D];
1338 Data.Attributes = A;
1339 Data.RefExpr.setPointer(E);
1340 Data.PrivateCopy = nullptr;
1341 Data.Modifier = Modifier;
1342 } else {
1343 DSAInfo &Data = getTopOfStack().SharingMap[D];
1344 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1347, __PRETTY_FUNCTION__))
1345 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1347, __PRETTY_FUNCTION__))
1346 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1347, __PRETTY_FUNCTION__))
1347 (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1347, __PRETTY_FUNCTION__))
;
1348 Data.Modifier = Modifier;
1349 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1350 Data.RefExpr.setInt(/*IntVal=*/true);
1351 return;
1352 }
1353 const bool IsLastprivate =
1354 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1355 Data.Attributes = A;
1356 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1357 Data.PrivateCopy = PrivateCopy;
1358 if (PrivateCopy) {
1359 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1360 Data.Modifier = Modifier;
1361 Data.Attributes = A;
1362 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1363 Data.PrivateCopy = nullptr;
1364 }
1365 }
1366}
1367
1368/// Build a variable declaration for OpenMP loop iteration variable.
1369static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1370 StringRef Name, const AttrVec *Attrs = nullptr,
1371 DeclRefExpr *OrigRef = nullptr) {
1372 DeclContext *DC = SemaRef.CurContext;
1373 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1374 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1375 auto *Decl =
1376 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1377 if (Attrs) {
1378 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1379 I != E; ++I)
1380 Decl->addAttr(*I);
1381 }
1382 Decl->setImplicit();
1383 if (OrigRef) {
1384 Decl->addAttr(
1385 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1386 }
1387 return Decl;
1388}
1389
1390static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1391 SourceLocation Loc,
1392 bool RefersToCapture = false) {
1393 D->setReferenced();
1394 D->markUsed(S.Context);
1395 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1396 SourceLocation(), D, RefersToCapture, Loc, Ty,
1397 VK_LValue);
1398}
1399
1400void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1401 BinaryOperatorKind BOK) {
1402 D = getCanonicalDecl(D);
1403 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1403, __PRETTY_FUNCTION__))
;
1404 assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1406, __PRETTY_FUNCTION__))
1405 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1406, __PRETTY_FUNCTION__))
1406 "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1406, __PRETTY_FUNCTION__))
;
1407 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1408 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1409 (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1410 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1411 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1412 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1413 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
1414 "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1414, __PRETTY_FUNCTION__))
;
1415 ReductionData.set(BOK, SR);
1416 Expr *&TaskgroupReductionRef =
1417 getTopOfStack().TaskgroupReductionRef;
1418 if (!TaskgroupReductionRef) {
1419 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1420 SemaRef.Context.VoidPtrTy, ".task_red.");
1421 TaskgroupReductionRef =
1422 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1423 }
1424}
1425
1426void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 const Expr *ReductionRef) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1429, __PRETTY_FUNCTION__))
;
1430 assert(((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1432, __PRETTY_FUNCTION__))
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1432, __PRETTY_FUNCTION__))
1432 "Additional reduction info may be specified only for reduction items.")((getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
"Additional reduction info may be specified only for reduction items."
) ? static_cast<void> (0) : __assert_fail ("getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1432, __PRETTY_FUNCTION__))
;
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1435 (getTopOfStack().Directive == OMPD_taskgroup ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1439 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
1440 "items.")((ReductionData.ReductionRange.isInvalid() && (getTopOfStack
().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective
(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack
().Directive)) && !isOpenMPSimdDirective(getTopOfStack
().Directive))) && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && (getTopOfStack().Directive == OMPD_taskgroup || ((isOpenMPParallelDirective(getTopOfStack().Directive) || isOpenMPWorksharingDirective(getTopOfStack().Directive)) && !isOpenMPSimdDirective(getTopOfStack().Directive))) && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1440, __PRETTY_FUNCTION__))
;
1441 ReductionData.set(ReductionRef, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1449 }
1450}
1451
1452const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1453 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1454 Expr *&TaskgroupDescriptor) const {
1455 D = getCanonicalDecl(D);
1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1456, __PRETTY_FUNCTION__))
;
1457 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1458 const DSAInfo &Data = I->SharingMap.lookup(D);
1459 if (Data.Attributes != OMPC_reduction ||
1460 Data.Modifier != OMPC_REDUCTION_task)
1461 continue;
1462 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1463 if (!ReductionData.ReductionOp ||
1464 ReductionData.ReductionOp.is<const Expr *>())
1465 return DSAVarData();
1466 SR = ReductionData.ReductionRange;
1467 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1468 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1470, __PRETTY_FUNCTION__))
1469 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1470, __PRETTY_FUNCTION__))
1470 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1470, __PRETTY_FUNCTION__))
;
1471 TaskgroupDescriptor = I->TaskgroupReductionRef;
1472 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1473 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1474 }
1475 return DSAVarData();
1476}
1477
1478const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1482, __PRETTY_FUNCTION__))
;
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1487 continue;
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 !ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1496, __PRETTY_FUNCTION__))
1495 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1496, __PRETTY_FUNCTION__))
1496 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1496, __PRETTY_FUNCTION__))
;
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1500 }
1501 return DSAVarData();
1502}
1503
1504bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1505 D = D->getCanonicalDecl();
1506 for (const_iterator E = end(); I != E; ++I) {
1507 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1508 isOpenMPTargetExecutionDirective(I->Directive)) {
1509 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1510 Scope *CurScope = getCurScope();
1511 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1512 CurScope = CurScope->getParent();
1513 return CurScope != TopScope;
1514 }
1515 }
1516 return false;
1517}
1518
1519static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1520 bool AcceptIfMutable = true,
1521 bool *IsClassType = nullptr) {
1522 ASTContext &Context = SemaRef.getASTContext();
1523 Type = Type.getNonReferenceType().getCanonicalType();
1524 bool IsConstant = Type.isConstant(Context);
1525 Type = Context.getBaseElementType(Type);
1526 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1527 ? Type->getAsCXXRecordDecl()
1528 : nullptr;
1529 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1530 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1531 RD = CTD->getTemplatedDecl();
1532 if (IsClassType)
1533 *IsClassType = RD;
1534 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1535 RD->hasDefinition() && RD->hasMutableFields());
1536}
1537
1538static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1539 QualType Type, OpenMPClauseKind CKind,
1540 SourceLocation ELoc,
1541 bool AcceptIfMutable = true,
1542 bool ListItemNotVar = false) {
1543 ASTContext &Context = SemaRef.getASTContext();
1544 bool IsClassType;
1545 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1546 unsigned Diag = ListItemNotVar
1547 ? diag::err_omp_const_list_item
1548 : IsClassType ? diag::err_omp_const_not_mutable_variable
1549 : diag::err_omp_const_variable;
1550 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1551 if (!ListItemNotVar && D) {
1552 const VarDecl *VD = dyn_cast<VarDecl>(D);
1553 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1554 VarDecl::DeclarationOnly;
1555 SemaRef.Diag(D->getLocation(),
1556 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1557 << D;
1558 }
1559 return true;
1560 }
1561 return false;
1562}
1563
1564const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1565 bool FromParent) {
1566 D = getCanonicalDecl(D);
1567 DSAVarData DVar;
1568
1569 auto *VD = dyn_cast<VarDecl>(D);
1570 auto TI = Threadprivates.find(D);
1571 if (TI != Threadprivates.end()) {
1572 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1573 DVar.CKind = OMPC_threadprivate;
1574 DVar.Modifier = TI->getSecond().Modifier;
1575 return DVar;
1576 }
1577 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1578 DVar.RefExpr = buildDeclRefExpr(
1579 SemaRef, VD, D->getType().getNonReferenceType(),
1580 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1581 DVar.CKind = OMPC_threadprivate;
1582 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1583 return DVar;
1584 }
1585 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1586 // in a Construct, C/C++, predetermined, p.1]
1587 // Variables appearing in threadprivate directives are threadprivate.
1588 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1589 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1590 SemaRef.getLangOpts().OpenMPUseTLS &&
1591 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1592 (VD && VD->getStorageClass() == SC_Register &&
1593 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1594 DVar.RefExpr = buildDeclRefExpr(
1595 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1596 DVar.CKind = OMPC_threadprivate;
1597 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1598 return DVar;
1599 }
1600 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1601 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1602 !isLoopControlVariable(D).first) {
1603 const_iterator IterTarget =
1604 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1605 return isOpenMPTargetExecutionDirective(Data.Directive);
1606 });
1607 if (IterTarget != end()) {
1608 const_iterator ParentIterTarget = IterTarget + 1;
1609 for (const_iterator Iter = begin();
1610 Iter != ParentIterTarget; ++Iter) {
1611 if (isOpenMPLocal(VD, Iter)) {
1612 DVar.RefExpr =
1613 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1614 D->getLocation());
1615 DVar.CKind = OMPC_threadprivate;
1616 return DVar;
1617 }
1618 }
1619 if (!isClauseParsingMode() || IterTarget != begin()) {
1620 auto DSAIter = IterTarget->SharingMap.find(D);
1621 if (DSAIter != IterTarget->SharingMap.end() &&
1622 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1623 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1624 DVar.CKind = OMPC_threadprivate;
1625 return DVar;
1626 }
1627 const_iterator End = end();
1628 if (!SemaRef.isOpenMPCapturedByRef(
1629 D, std::distance(ParentIterTarget, End),
1630 /*OpenMPCaptureLevel=*/0)) {
1631 DVar.RefExpr =
1632 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1633 IterTarget->ConstructLoc);
1634 DVar.CKind = OMPC_threadprivate;
1635 return DVar;
1636 }
1637 }
1638 }
1639 }
1640
1641 if (isStackEmpty())
1642 // Not in OpenMP execution region and top scope was already checked.
1643 return DVar;
1644
1645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1646 // in a Construct, C/C++, predetermined, p.4]
1647 // Static data members are shared.
1648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1649 // in a Construct, C/C++, predetermined, p.7]
1650 // Variables with static storage duration that are declared in a scope
1651 // inside the construct are shared.
1652 if (VD && VD->isStaticDataMember()) {
1653 // Check for explicitly specified attributes.
1654 const_iterator I = begin();
1655 const_iterator EndI = end();
1656 if (FromParent && I != EndI)
1657 ++I;
1658 if (I != EndI) {
1659 auto It = I->SharingMap.find(D);
1660 if (It != I->SharingMap.end()) {
1661 const DSAInfo &Data = It->getSecond();
1662 DVar.RefExpr = Data.RefExpr.getPointer();
1663 DVar.PrivateCopy = Data.PrivateCopy;
1664 DVar.CKind = Data.Attributes;
1665 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1666 DVar.DKind = I->Directive;
1667 DVar.Modifier = Data.Modifier;
1668 return DVar;
1669 }
1670 }
1671
1672 DVar.CKind = OMPC_shared;
1673 return DVar;
1674 }
1675
1676 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1677 // The predetermined shared attribute for const-qualified types having no
1678 // mutable members was removed after OpenMP 3.1.
1679 if (SemaRef.LangOpts.OpenMP <= 31) {
1680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1681 // in a Construct, C/C++, predetermined, p.6]
1682 // Variables with const qualified type having no mutable member are
1683 // shared.
1684 if (isConstNotMutableType(SemaRef, D->getType())) {
1685 // Variables with const-qualified type having no mutable member may be
1686 // listed in a firstprivate clause, even if they are static data members.
1687 DSAVarData DVarTemp = hasInnermostDSA(
1688 D,
1689 [](OpenMPClauseKind C) {
1690 return C == OMPC_firstprivate || C == OMPC_shared;
1691 },
1692 MatchesAlways, FromParent);
1693 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1694 return DVarTemp;
1695
1696 DVar.CKind = OMPC_shared;
1697 return DVar;
1698 }
1699 }
1700
1701 // Explicitly specified attributes and local variables with predetermined
1702 // attributes.
1703 const_iterator I = begin();
1704 const_iterator EndI = end();
1705 if (FromParent && I != EndI)
1706 ++I;
1707 if (I == EndI)
1708 return DVar;
1709 auto It = I->SharingMap.find(D);
1710 if (It != I->SharingMap.end()) {
1711 const DSAInfo &Data = It->getSecond();
1712 DVar.RefExpr = Data.RefExpr.getPointer();
1713 DVar.PrivateCopy = Data.PrivateCopy;
1714 DVar.CKind = Data.Attributes;
1715 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716 DVar.DKind = I->Directive;
1717 DVar.Modifier = Data.Modifier;
1718 }
1719
1720 return DVar;
1721}
1722
1723const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1724 bool FromParent) const {
1725 if (isStackEmpty()) {
1726 const_iterator I;
1727 return getDSA(I, D);
1728 }
1729 D = getCanonicalDecl(D);
1730 const_iterator StartI = begin();
1731 const_iterator EndI = end();
1732 if (FromParent && StartI != EndI)
1733 ++StartI;
1734 return getDSA(StartI, D);
1735}
1736
1737const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1738 unsigned Level) const {
1739 if (getStackSize() <= Level)
1740 return DSAVarData();
1741 D = getCanonicalDecl(D);
1742 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1743 return getDSA(StartI, D);
1744}
1745
1746const DSAStackTy::DSAVarData
1747DSAStackTy::hasDSA(ValueDecl *D,
1748 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1749 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1750 bool FromParent) const {
1751 if (isStackEmpty())
1752 return {};
1753 D = getCanonicalDecl(D);
1754 const_iterator I = begin();
1755 const_iterator EndI = end();
1756 if (FromParent && I != EndI)
1757 ++I;
1758 for (; I != EndI; ++I) {
1759 if (!DPred(I->Directive) &&
1760 !isImplicitOrExplicitTaskingRegion(I->Directive))
1761 continue;
1762 const_iterator NewI = I;
1763 DSAVarData DVar = getDSA(NewI, D);
1764 if (I == NewI && CPred(DVar.CKind))
1765 return DVar;
1766 }
1767 return {};
1768}
1769
1770const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1771 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1772 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1773 bool FromParent) const {
1774 if (isStackEmpty())
1775 return {};
1776 D = getCanonicalDecl(D);
1777 const_iterator StartI = begin();
1778 const_iterator EndI = end();
1779 if (FromParent && StartI != EndI)
1780 ++StartI;
1781 if (StartI == EndI || !DPred(StartI->Directive))
1782 return {};
1783 const_iterator NewI = StartI;
1784 DSAVarData DVar = getDSA(NewI, D);
1785 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1786}
1787
1788bool DSAStackTy::hasExplicitDSA(
1789 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1790 unsigned Level, bool NotLastprivate) const {
1791 if (getStackSize() <= Level)
1792 return false;
1793 D = getCanonicalDecl(D);
1794 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1795 auto I = StackElem.SharingMap.find(D);
1796 if (I != StackElem.SharingMap.end() &&
1797 I->getSecond().RefExpr.getPointer() &&
1798 CPred(I->getSecond().Attributes) &&
1799 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1800 return true;
1801 // Check predetermined rules for the loop control variables.
1802 auto LI = StackElem.LCVMap.find(D);
1803 if (LI != StackElem.LCVMap.end())
1804 return CPred(OMPC_private);
1805 return false;
1806}
1807
1808bool DSAStackTy::hasExplicitDirective(
1809 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1810 unsigned Level) const {
1811 if (getStackSize() <= Level)
1812 return false;
1813 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1814 return DPred(StackElem.Directive);
1815}
1816
1817bool DSAStackTy::hasDirective(
1818 const llvm::function_ref<bool(OpenMPDirectiveKind,
1819 const DeclarationNameInfo &, SourceLocation)>
1820 DPred,
1821 bool FromParent) const {
1822 // We look only in the enclosing region.
1823 size_t Skip = FromParent ? 2 : 1;
1824 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1825 I != E; ++I) {
1826 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1827 return true;
1828 }
1829 return false;
1830}
1831
1832void Sema::InitDataSharingAttributesStack() {
1833 VarDataSharingAttributesStack = new DSAStackTy(*this);
1834}
1835
1836#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1837
1838void Sema::pushOpenMPFunctionRegion() {
1839 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1840}
1841
1842void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1843 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1844}
1845
1846static bool isOpenMPDeviceDelayedContext(Sema &S) {
1847 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1848, __PRETTY_FUNCTION__))
1848 "Expected OpenMP device compilation.")((S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1848, __PRETTY_FUNCTION__))
;
1849 return !S.isInOpenMPTargetExecutionDirective() &&
1850 !S.isInOpenMPDeclareTargetContext();
1851}
1852
1853namespace {
1854/// Status of the function emission on the host/device.
1855enum class FunctionEmissionStatus {
1856 Emitted,
1857 Discarded,
1858 Unknown,
1859};
1860} // anonymous namespace
1861
1862Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1863 unsigned DiagID) {
1864 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1865, __PRETTY_FUNCTION__))
1865 "Expected OpenMP device compilation.")((LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
"Expected OpenMP device compilation.") ? static_cast<void
> (0) : __assert_fail ("LangOpts.OpenMP && LangOpts.OpenMPIsDevice && \"Expected OpenMP device compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1865, __PRETTY_FUNCTION__))
;
1866
1867 FunctionDecl *FD = getCurFunctionDecl();
1868 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1869 if (FD) {
1870 FunctionEmissionStatus FES = getEmissionStatus(FD);
1871 switch (FES) {
1872 case FunctionEmissionStatus::Emitted:
1873 Kind = DeviceDiagBuilder::K_Immediate;
1874 break;
1875 case FunctionEmissionStatus::Unknown:
1876 Kind = isOpenMPDeviceDelayedContext(*this)
1877 ? DeviceDiagBuilder::K_Deferred
1878 : DeviceDiagBuilder::K_Immediate;
1879 break;
1880 case FunctionEmissionStatus::TemplateDiscarded:
1881 case FunctionEmissionStatus::OMPDiscarded:
1882 Kind = DeviceDiagBuilder::K_Nop;
1883 break;
1884 case FunctionEmissionStatus::CUDADiscarded:
1885 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1885)
;
1886 break;
1887 }
1888 }
1889
1890 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1891}
1892
1893Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1894 unsigned DiagID) {
1895 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
"Expected OpenMP host compilation.") ? static_cast<void>
(0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1896, __PRETTY_FUNCTION__))
1896 "Expected OpenMP host compilation.")((LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
"Expected OpenMP host compilation.") ? static_cast<void>
(0) : __assert_fail ("LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && \"Expected OpenMP host compilation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1896, __PRETTY_FUNCTION__))
;
1897 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1898 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1899 switch (FES) {
1900 case FunctionEmissionStatus::Emitted:
1901 Kind = DeviceDiagBuilder::K_Immediate;
1902 break;
1903 case FunctionEmissionStatus::Unknown:
1904 Kind = DeviceDiagBuilder::K_Deferred;
1905 break;
1906 case FunctionEmissionStatus::TemplateDiscarded:
1907 case FunctionEmissionStatus::OMPDiscarded:
1908 case FunctionEmissionStatus::CUDADiscarded:
1909 Kind = DeviceDiagBuilder::K_Nop;
1910 break;
1911 }
1912
1913 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1914}
1915
1916static OpenMPDefaultmapClauseKind
1917getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1918 if (LO.OpenMP <= 45) {
1919 if (VD->getType().getNonReferenceType()->isScalarType())
1920 return OMPC_DEFAULTMAP_scalar;
1921 return OMPC_DEFAULTMAP_aggregate;
1922 }
1923 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1924 return OMPC_DEFAULTMAP_pointer;
1925 if (VD->getType().getNonReferenceType()->isScalarType())
1926 return OMPC_DEFAULTMAP_scalar;
1927 return OMPC_DEFAULTMAP_aggregate;
1928}
1929
1930bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1931 unsigned OpenMPCaptureLevel) const {
1932 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 1932, __PRETTY_FUNCTION__))
;
1933
1934 ASTContext &Ctx = getASTContext();
1935 bool IsByRef = true;
1936
1937 // Find the directive that is associated with the provided scope.
1938 D = cast<ValueDecl>(D->getCanonicalDecl());
1939 QualType Ty = D->getType();
1940
1941 bool IsVariableUsedInMapClause = false;
1942 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1943 // This table summarizes how a given variable should be passed to the device
1944 // given its type and the clauses where it appears. This table is based on
1945 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1946 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1947 //
1948 // =========================================================================
1949 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1950 // | |(tofrom:scalar)| | pvt | | | |
1951 // =========================================================================
1952 // | scl | | | | - | | bycopy|
1953 // | scl | | - | x | - | - | bycopy|
1954 // | scl | | x | - | - | - | null |
1955 // | scl | x | | | - | | byref |
1956 // | scl | x | - | x | - | - | bycopy|
1957 // | scl | x | x | - | - | - | null |
1958 // | scl | | - | - | - | x | byref |
1959 // | scl | x | - | - | - | x | byref |
1960 //
1961 // | agg | n.a. | | | - | | byref |
1962 // | agg | n.a. | - | x | - | - | byref |
1963 // | agg | n.a. | x | - | - | - | null |
1964 // | agg | n.a. | - | - | - | x | byref |
1965 // | agg | n.a. | - | - | - | x[] | byref |
1966 //
1967 // | ptr | n.a. | | | - | | bycopy|
1968 // | ptr | n.a. | - | x | - | - | bycopy|
1969 // | ptr | n.a. | x | - | - | - | null |
1970 // | ptr | n.a. | - | - | - | x | byref |
1971 // | ptr | n.a. | - | - | - | x[] | bycopy|
1972 // | ptr | n.a. | - | - | x | | bycopy|
1973 // | ptr | n.a. | - | - | x | x | bycopy|
1974 // | ptr | n.a. | - | - | x | x[] | bycopy|
1975 // =========================================================================
1976 // Legend:
1977 // scl - scalar
1978 // ptr - pointer
1979 // agg - aggregate
1980 // x - applies
1981 // - - invalid in this combination
1982 // [] - mapped with an array section
1983 // byref - should be mapped by reference
1984 // byval - should be mapped by value
1985 // null - initialize a local variable to null on the device
1986 //
1987 // Observations:
1988 // - All scalar declarations that show up in a map clause have to be passed
1989 // by reference, because they may have been mapped in the enclosing data
1990 // environment.
1991 // - If the scalar value does not fit the size of uintptr, it has to be
1992 // passed by reference, regardless the result in the table above.
1993 // - For pointers mapped by value that have either an implicit map or an
1994 // array section, the runtime library may pass the NULL value to the
1995 // device instead of the value passed to it by the compiler.
1996
1997 if (Ty->isReferenceType())
1998 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1999
2000 // Locate map clauses and see if the variable being captured is referred to
2001 // in any of those clauses. Here we only care about variables, not fields,
2002 // because fields are part of aggregates.
2003 bool IsVariableAssociatedWithSection = false;
2004
2005 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2006 D, Level,
2007 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2008 OMPClauseMappableExprCommon::MappableExprComponentListRef
2009 MapExprComponents,
2010 OpenMPClauseKind WhereFoundClauseKind) {
2011 // Only the map clause information influences how a variable is
2012 // captured. E.g. is_device_ptr does not require changing the default
2013 // behavior.
2014 if (WhereFoundClauseKind != OMPC_map)
2015 return false;
2016
2017 auto EI = MapExprComponents.rbegin();
2018 auto EE = MapExprComponents.rend();
2019
2020 assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast
<void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2020, __PRETTY_FUNCTION__))
;
2021
2022 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2023 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2024
2025 ++EI;
2026 if (EI == EE)
2027 return false;
2028
2029 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2030 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2031 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2032 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2033 IsVariableAssociatedWithSection = true;
2034 // There is nothing more we need to know about this variable.
2035 return true;
2036 }
2037
2038 // Keep looking for more map info.
2039 return false;
2040 });
2041
2042 if (IsVariableUsedInMapClause) {
2043 // If variable is identified in a map clause it is always captured by
2044 // reference except if it is a pointer that is dereferenced somehow.
2045 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2046 } else {
2047 // By default, all the data that has a scalar type is mapped by copy
2048 // (except for reduction variables).
2049 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2050 IsByRef =
2051 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
2052 !Ty->isAnyPointerType()) ||
2053 !Ty->isScalarType() ||
2054 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
2055 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2056 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2057 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
2058 }
2059 }
2060
2061 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2062 IsByRef =
2063 ((IsVariableUsedInMapClause &&
2064 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2065 OMPD_target) ||
2066 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2067 D,
2068 [](OpenMPClauseKind K) -> bool {
2069 return K == OMPC_firstprivate;
2070 },
2071 Level, /*NotLastprivate=*/true) ||
2072 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D))) &&
2073 // If the variable is artificial and must be captured by value - try to
2074 // capture by value.
2075 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2076 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2077 // If the variable is implicitly firstprivate and scalar - capture by
2078 // copy
2079 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate &&
2080 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2081 D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) &&
2082 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first);
2083 }
2084
2085 // When passing data by copy, we need to make sure it fits the uintptr size
2086 // and alignment, because the runtime library only deals with uintptr types.
2087 // If it does not fit the uintptr size, we need to pass the data by reference
2088 // instead.
2089 if (!IsByRef &&
2090 (Ctx.getTypeSizeInChars(Ty) >
2091 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2092 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2093 IsByRef = true;
2094 }
2095
2096 return IsByRef;
2097}
2098
2099unsigned Sema::getOpenMPNestingLevel() const {
2100 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2100, __PRETTY_FUNCTION__))
;
2101 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
2102}
2103
2104bool Sema::isInOpenMPTargetExecutionDirective() const {
2105 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2106 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2107 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2108 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2109 SourceLocation) -> bool {
2110 return isOpenMPTargetExecutionDirective(K);
2111 },
2112 false);
2113}
2114
2115VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2116 unsigned StopAt) {
2117 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2117, __PRETTY_FUNCTION__))
;
2118 D = getCanonicalDecl(D);
2119
2120 auto *VD = dyn_cast<VarDecl>(D);
2121 // Do not capture constexpr variables.
2122 if (VD && VD->isConstexpr())
2123 return nullptr;
2124
2125 // If we want to determine whether the variable should be captured from the
2126 // perspective of the current capturing scope, and we've already left all the
2127 // capturing scopes of the top directive on the stack, check from the
2128 // perspective of its parent directive (if any) instead.
2129 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2130 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2131
2132 // If we are attempting to capture a global variable in a directive with
2133 // 'target' we return true so that this global is also mapped to the device.
2134 //
2135 if (VD && !VD->hasLocalStorage() &&
2136 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2137 if (isInOpenMPDeclareTargetContext()) {
2138 // Try to mark variable as declare target if it is used in capturing
2139 // regions.
2140 if (LangOpts.OpenMP <= 45 &&
2141 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2142 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2143 return nullptr;
2144 } else if (isInOpenMPTargetExecutionDirective()) {
2145 // If the declaration is enclosed in a 'declare target' directive,
2146 // then it should not be captured.
2147 //
2148 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2149 return nullptr;
2150 CapturedRegionScopeInfo *CSI = nullptr;
2151 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2152 llvm::reverse(FunctionScopes),
2153 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2154 if (!isa<CapturingScopeInfo>(FSI))
2155 return nullptr;
2156 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2157 if (RSI->CapRegionKind == CR_OpenMP) {
2158 CSI = RSI;
2159 break;
2160 }
2161 }
2162 SmallVector<OpenMPDirectiveKind, 4> Regions;
2163 getOpenMPCaptureRegions(Regions,
2164 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2165 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2166 return VD;
2167 }
2168 }
2169
2170 if (CheckScopeInfo) {
2171 bool OpenMPFound = false;
2172 for (unsigned I = StopAt + 1; I > 0; --I) {
2173 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2174 if(!isa<CapturingScopeInfo>(FSI))
2175 return nullptr;
2176 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2177 if (RSI->CapRegionKind == CR_OpenMP) {
2178 OpenMPFound = true;
2179 break;
2180 }
2181 }
2182 if (!OpenMPFound)
2183 return nullptr;
2184 }
2185
2186 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2187 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2188 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2189 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2190 if (Info.first ||
2191 (VD && VD->hasLocalStorage() &&
2192 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2193 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2194 return VD ? VD : Info.second;
2195 DSAStackTy::DSAVarData DVarTop =
2196 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2197 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind))
2198 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2199 // Threadprivate variables must not be captured.
2200 if (isOpenMPThreadPrivate(DVarTop.CKind))
2201 return nullptr;
2202 // The variable is not private or it is the variable in the directive with
2203 // default(none) clause and not used in any clause.
2204 DSAStackTy::DSAVarData DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
2205 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
2206 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2207 // Global shared must not be captured.
2208 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2209 ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_none &&
2210 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() != DSA_firstprivate) ||
2211 DVarTop.CKind == OMPC_shared))
2212 return nullptr;
2213 if (DVarPrivate.CKind != OMPC_unknown ||
2214 (VD && (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
2215 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate)))
2216 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2217 }
2218 return nullptr;
2219}
2220
2221void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2222 unsigned Level) const {
2223 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2224}
2225
2226void Sema::startOpenMPLoop() {
2227 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2227, __PRETTY_FUNCTION__))
;
2228 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2229 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2230}
2231
2232void Sema::startOpenMPCXXRangeFor() {
2233 assert(LangOpts.OpenMP && "OpenMP must be enabled.")((LangOpts.OpenMP && "OpenMP must be enabled.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP must be enabled.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2233, __PRETTY_FUNCTION__))
;
2234 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2235 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2236 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2237 }
2238}
2239
2240OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2241 unsigned CapLevel) const {
2242 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2242, __PRETTY_FUNCTION__))
;
2243 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2244 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2245 Level)) {
2246 bool IsTriviallyCopyable =
2247 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2248 !D->getType()
2249 .getNonReferenceType()
2250 .getCanonicalType()
2251 ->getAsCXXRecordDecl();
2252 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level);
2253 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2254 getOpenMPCaptureRegions(CaptureRegions, DKind);
2255 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2256 (IsTriviallyCopyable ||
2257 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2258 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2259 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; },
2260 Level, /*NotLastprivate=*/true))
2261 return OMPC_firstprivate;
2262 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level);
2263 if (DVar.CKind != OMPC_shared &&
2264 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2265 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addImplicitTaskFirstprivate(Level, D);
2266 return OMPC_firstprivate;
2267 }
2268 }
2269 }
2270 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2271 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2272 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2273 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2275 return OMPC_private;
2276 }
2277 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2278 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2279 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2280 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2281 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2282 return OMPC_private;
2283 }
2284 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2285 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2286 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2287 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2288 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2289 return OMPC_private;
2290 }
2291 // User-defined allocators are private since they must be defined in the
2292 // context of target region.
2293 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2294 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isUsesAllocatorsDecl(Level, D).getValueOr(
2295 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2296 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2297 return OMPC_private;
2298 return (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2299 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2300 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2301 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2302 // Consider taskgroup reduction descriptor variable a private
2303 // to avoid possible capture in the region.
2304 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2305 [](OpenMPDirectiveKind K) {
2306 return K == OMPD_taskgroup ||
2307 ((isOpenMPParallelDirective(K) ||
2308 isOpenMPWorksharingDirective(K)) &&
2309 !isOpenMPSimdDirective(K));
2310 },
2311 Level) &&
2312 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level)))
2313 ? OMPC_private
2314 : OMPC_unknown;
2315}
2316
2317void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2318 unsigned Level) {
2319 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2319, __PRETTY_FUNCTION__))
;
2320 D = getCanonicalDecl(D);
2321 OpenMPClauseKind OMPC = OMPC_unknown;
2322 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2323 const unsigned NewLevel = I - 1;
2324 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
2325 [&OMPC](const OpenMPClauseKind K) {
2326 if (isOpenMPPrivate(K)) {
2327 OMPC = K;
2328 return true;
2329 }
2330 return false;
2331 },
2332 NewLevel))
2333 break;
2334 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2335 D, NewLevel,
2336 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2337 OpenMPClauseKind) { return true; })) {
2338 OMPC = OMPC_map;
2339 break;
2340 }
2341 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2342 NewLevel)) {
2343 OMPC = OMPC_map;
2344 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2345 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2346 OMPC = OMPC_firstprivate;
2347 break;
2348 }
2349 }
2350 if (OMPC != OMPC_unknown)
2351 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2352}
2353
2354bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2355 unsigned CaptureLevel) const {
2356 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2356, __PRETTY_FUNCTION__))
;
2357 // Return true if the current level is no longer enclosed in a target region.
2358
2359 SmallVector<OpenMPDirectiveKind, 4> Regions;
2360 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2361 const auto *VD = dyn_cast<VarDecl>(D);
2362 return VD && !VD->hasLocalStorage() &&
2363 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2364 Level) &&
2365 Regions[CaptureLevel] != OMPD_task;
2366}
2367
2368bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2369 unsigned CaptureLevel) const {
2370 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2370, __PRETTY_FUNCTION__))
;
2371 // Return true if the current level is no longer enclosed in a target region.
2372
2373 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2374 if (!VD->hasLocalStorage()) {
2375 DSAStackTy::DSAVarData TopDVar =
2376 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2377 unsigned NumLevels =
2378 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2379 if (Level == 0)
2380 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2381 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, Level - 1);
2382 return DVar.CKind != OMPC_shared ||
2383 isOpenMPGlobalCapturedDecl(
2384 D, Level - 1,
2385 getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level - 1)) - 1);
2386 }
2387 }
2388 return true;
2389}
2390
2391void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2392
2393void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2394 OMPTraitInfo &TI) {
2395 if (!OMPDeclareVariantScopes.empty()) {
2396 Diag(Loc, diag::warn_nested_declare_variant);
2397 return;
2398 }
2399 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2400}
2401
2402void Sema::ActOnOpenMPEndDeclareVariant() {
2403 assert(isInOpenMPDeclareVariantScope() &&((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2404, __PRETTY_FUNCTION__))
2404 "Not in OpenMP declare variant scope!")((isInOpenMPDeclareVariantScope() && "Not in OpenMP declare variant scope!"
) ? static_cast<void> (0) : __assert_fail ("isInOpenMPDeclareVariantScope() && \"Not in OpenMP declare variant scope!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2404, __PRETTY_FUNCTION__))
;
2405
2406 OMPDeclareVariantScopes.pop_back();
2407}
2408
2409void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2410 const FunctionDecl *Callee,
2411 SourceLocation Loc) {
2412 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.")((LangOpts.OpenMP && "Expected OpenMP compilation mode."
) ? static_cast<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP compilation mode.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2412, __PRETTY_FUNCTION__))
;
2413 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2414 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2415 // Ignore host functions during device analyzis.
2416 if (LangOpts.OpenMPIsDevice && DevTy &&
2417 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2418 return;
2419 // Ignore nohost functions during host analyzis.
2420 if (!LangOpts.OpenMPIsDevice && DevTy &&
2421 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2422 return;
2423 const FunctionDecl *FD = Callee->getMostRecentDecl();
2424 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2425 if (LangOpts.OpenMPIsDevice && DevTy &&
2426 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2427 // Diagnose host function called during device codegen.
2428 StringRef HostDevTy =
2429 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2430 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2431 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2432 diag::note_omp_marked_device_type_here)
2433 << HostDevTy;
2434 return;
2435 }
2436 if (!LangOpts.OpenMPIsDevice && DevTy &&
2437 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2438 // Diagnose nohost function called during host codegen.
2439 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2440 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2441 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2442 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2443 diag::note_omp_marked_device_type_here)
2444 << NoHostDevTy;
2445 }
2446}
2447
2448void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2449 const DeclarationNameInfo &DirName,
2450 Scope *CurScope, SourceLocation Loc) {
2451 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2452 PushExpressionEvaluationContext(
2453 ExpressionEvaluationContext::PotentiallyEvaluated);
2454}
2455
2456void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2457 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2458}
2459
2460void Sema::EndOpenMPClause() {
2461 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2462}
2463
2464static std::pair<ValueDecl *, bool>
2465getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2466 SourceRange &ERange, bool AllowArraySection = false);
2467
2468/// Check consistency of the reduction clauses.
2469static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2470 ArrayRef<OMPClause *> Clauses) {
2471 bool InscanFound = false;
2472 SourceLocation InscanLoc;
2473 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2474 // A reduction clause without the inscan reduction-modifier may not appear on
2475 // a construct on which a reduction clause with the inscan reduction-modifier
2476 // appears.
2477 for (OMPClause *C : Clauses) {
2478 if (C->getClauseKind() != OMPC_reduction)
2479 continue;
2480 auto *RC = cast<OMPReductionClause>(C);
2481 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2482 InscanFound = true;
2483 InscanLoc = RC->getModifierLoc();
2484 continue;
2485 }
2486 if (RC->getModifier() == OMPC_REDUCTION_task) {
2487 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2488 // A reduction clause with the task reduction-modifier may only appear on
2489 // a parallel construct, a worksharing construct or a combined or
2490 // composite construct for which any of the aforementioned constructs is a
2491 // constituent construct and simd or loop are not constituent constructs.
2492 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2493 if (!(isOpenMPParallelDirective(CurDir) ||
2494 isOpenMPWorksharingDirective(CurDir)) ||
2495 isOpenMPSimdDirective(CurDir))
2496 S.Diag(RC->getModifierLoc(),
2497 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2498 continue;
2499 }
2500 }
2501 if (InscanFound) {
2502 for (OMPClause *C : Clauses) {
2503 if (C->getClauseKind() != OMPC_reduction)
2504 continue;
2505 auto *RC = cast<OMPReductionClause>(C);
2506 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2507 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2508 ? RC->getBeginLoc()
2509 : RC->getModifierLoc(),
2510 diag::err_omp_inscan_reduction_expected);
2511 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2512 continue;
2513 }
2514 for (Expr *Ref : RC->varlists()) {
2515 assert(Ref && "NULL expr in OpenMP nontemporal clause.")((Ref && "NULL expr in OpenMP nontemporal clause.") ?
static_cast<void> (0) : __assert_fail ("Ref && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2515, __PRETTY_FUNCTION__))
;
2516 SourceLocation ELoc;
2517 SourceRange ERange;
2518 Expr *SimpleRefExpr = Ref;
2519 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2520 /*AllowArraySection=*/true);
2521 ValueDecl *D = Res.first;
2522 if (!D)
2523 continue;
2524 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2525 S.Diag(Ref->getExprLoc(),
2526 diag::err_omp_reduction_not_inclusive_exclusive)
2527 << Ref->getSourceRange();
2528 }
2529 }
2530 }
2531 }
2532}
2533
2534static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2535 ArrayRef<OMPClause *> Clauses);
2536static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2537 bool WithInit);
2538
2539static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2540 const ValueDecl *D,
2541 const DSAStackTy::DSAVarData &DVar,
2542 bool IsLoopIterVar = false);
2543
2544void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2545 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2546 // A variable of class type (or array thereof) that appears in a lastprivate
2547 // clause requires an accessible, unambiguous default constructor for the
2548 // class type, unless the list item is also specified in a firstprivate
2549 // clause.
2550 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2551 for (OMPClause *C : D->clauses()) {
2552 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2553 SmallVector<Expr *, 8> PrivateCopies;
2554 for (Expr *DE : Clause->varlists()) {
2555 if (DE->isValueDependent() || DE->isTypeDependent()) {
2556 PrivateCopies.push_back(nullptr);
2557 continue;
2558 }
2559 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2560 auto *VD = cast<VarDecl>(DRE->getDecl());
2561 QualType Type = VD->getType().getNonReferenceType();
2562 const DSAStackTy::DSAVarData DVar =
2563 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2564 if (DVar.CKind == OMPC_lastprivate) {
2565 // Generate helper private variable and initialize it with the
2566 // default value. The address of the original variable is replaced
2567 // by the address of the new private variable in CodeGen. This new
2568 // variable is not added to IdResolver, so the code in the OpenMP
2569 // region uses original variable for proper diagnostics.
2570 VarDecl *VDPrivate = buildVarDecl(
2571 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2572 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2573 ActOnUninitializedDecl(VDPrivate);
2574 if (VDPrivate->isInvalidDecl()) {
2575 PrivateCopies.push_back(nullptr);
2576 continue;
2577 }
2578 PrivateCopies.push_back(buildDeclRefExpr(
2579 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2580 } else {
2581 // The variable is also a firstprivate, so initialization sequence
2582 // for private copy is generated already.
2583 PrivateCopies.push_back(nullptr);
2584 }
2585 }
2586 Clause->setPrivateCopies(PrivateCopies);
2587 continue;
2588 }
2589 // Finalize nontemporal clause by handling private copies, if any.
2590 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2591 SmallVector<Expr *, 8> PrivateRefs;
2592 for (Expr *RefExpr : Clause->varlists()) {
2593 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 2593, __PRETTY_FUNCTION__))
;
2594 SourceLocation ELoc;
2595 SourceRange ERange;
2596 Expr *SimpleRefExpr = RefExpr;
2597 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2598 if (Res.second)
2599 // It will be analyzed later.
2600 PrivateRefs.push_back(RefExpr);
2601 ValueDecl *D = Res.first;
2602 if (!D)
2603 continue;
2604
2605 const DSAStackTy::DSAVarData DVar =
2606 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2607 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2608 : SimpleRefExpr);
2609 }
2610 Clause->setPrivateRefs(PrivateRefs);
2611 continue;
2612 }
2613 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2614 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2615 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2616 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2617 if (!DRE)
2618 continue;
2619 ValueDecl *VD = DRE->getDecl();
2620 if (!VD || !isa<VarDecl>(VD))
2621 continue;
2622 DSAStackTy::DSAVarData DVar =
2623 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2624 // OpenMP [2.12.5, target Construct]
2625 // Memory allocators that appear in a uses_allocators clause cannot
2626 // appear in other data-sharing attribute clauses or data-mapping
2627 // attribute clauses in the same construct.
2628 Expr *MapExpr = nullptr;
2629 if (DVar.RefExpr ||
2630 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
2631 VD, /*CurrentRegionOnly=*/true,
2632 [VD, &MapExpr](
2633 OMPClauseMappableExprCommon::MappableExprComponentListRef
2634 MapExprComponents,
2635 OpenMPClauseKind C) {
2636 auto MI = MapExprComponents.rbegin();
2637 auto ME = MapExprComponents.rend();
2638 if (MI != ME &&
2639 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2640 VD->getCanonicalDecl()) {
2641 MapExpr = MI->getAssociatedExpression();
2642 return true;
2643 }
2644 return false;
2645 })) {
2646 Diag(D.Allocator->getExprLoc(),
2647 diag::err_omp_allocator_used_in_clauses)
2648 << D.Allocator->getSourceRange();
2649 if (DVar.RefExpr)
2650 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
2651 else
2652 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2653 << MapExpr->getSourceRange();
2654 }
2655 }
2656 continue;
2657 }
2658 }
2659 // Check allocate clauses.
2660 if (!CurContext->isDependentContext())
2661 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2662 checkReductionClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2663 }
2664
2665 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2666 DiscardCleanupsInEvaluationContext();
2667 PopExpressionEvaluationContext();
2668}
2669
2670static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2671 Expr *NumIterations, Sema &SemaRef,
2672 Scope *S, DSAStackTy *Stack);
2673
2674namespace {
2675
2676class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2677private:
2678 Sema &SemaRef;
2679
2680public:
2681 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2682 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2683 NamedDecl *ND = Candidate.getCorrectionDecl();
2684 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2685 return VD->hasGlobalStorage() &&
2686 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2687 SemaRef.getCurScope());
2688 }
2689 return false;
2690 }
2691
2692 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2693 return std::make_unique<VarDeclFilterCCC>(*this);
2694 }
2695
2696};
2697
2698class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2699private:
2700 Sema &SemaRef;
2701
2702public:
2703 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2704 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2705 NamedDecl *ND = Candidate.getCorrectionDecl();
2706 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2707 isa<FunctionDecl>(ND))) {
2708 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2709 SemaRef.getCurScope());
2710 }
2711 return false;
2712 }
2713
2714 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2715 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2716 }
2717};
2718
2719} // namespace
2720
2721ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2722 CXXScopeSpec &ScopeSpec,
2723 const DeclarationNameInfo &Id,
2724 OpenMPDirectiveKind Kind) {
2725 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2726 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2727
2728 if (Lookup.isAmbiguous())
2729 return ExprError();
2730
2731 VarDecl *VD;
2732 if (!Lookup.isSingleResult()) {
2733 VarDeclFilterCCC CCC(*this);
2734 if (TypoCorrection Corrected =
2735 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2736 CTK_ErrorRecovery)) {
2737 diagnoseTypo(Corrected,
2738 PDiag(Lookup.empty()
2739 ? diag::err_undeclared_var_use_suggest
2740 : diag::err_omp_expected_var_arg_suggest)
2741 << Id.getName());
2742 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2743 } else {
2744 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2745 : diag::err_omp_expected_var_arg)
2746 << Id.getName();
2747 return ExprError();
2748 }
2749 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2750 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2751 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2752 return ExprError();
2753 }
2754 Lookup.suppressDiagnostics();
2755
2756 // OpenMP [2.9.2, Syntax, C/C++]
2757 // Variables must be file-scope, namespace-scope, or static block-scope.
2758 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2759 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2760 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2761 bool IsDecl =
2762 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2763 Diag(VD->getLocation(),
2764 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2765 << VD;
2766 return ExprError();
2767 }
2768
2769 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2770 NamedDecl *ND = CanonicalVD;
2771 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2772 // A threadprivate directive for file-scope variables must appear outside
2773 // any definition or declaration.
2774 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2775 !getCurLexicalContext()->isTranslationUnit()) {
2776 Diag(Id.getLoc(), diag::err_omp_var_scope)
2777 << getOpenMPDirectiveName(Kind) << VD;
2778 bool IsDecl =
2779 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2780 Diag(VD->getLocation(),
2781 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2782 << VD;
2783 return ExprError();
2784 }
2785 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2786 // A threadprivate directive for static class member variables must appear
2787 // in the class definition, in the same scope in which the member
2788 // variables are declared.
2789 if (CanonicalVD->isStaticDataMember() &&
2790 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2791 Diag(Id.getLoc(), diag::err_omp_var_scope)
2792 << getOpenMPDirectiveName(Kind) << VD;
2793 bool IsDecl =
2794 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2795 Diag(VD->getLocation(),
2796 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2797 << VD;
2798 return ExprError();
2799 }
2800 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2801 // A threadprivate directive for namespace-scope variables must appear
2802 // outside any definition or declaration other than the namespace
2803 // definition itself.
2804 if (CanonicalVD->getDeclContext()->isNamespace() &&
2805 (!getCurLexicalContext()->isFileContext() ||
2806 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2807 Diag(Id.getLoc(), diag::err_omp_var_scope)
2808 << getOpenMPDirectiveName(Kind) << VD;
2809 bool IsDecl =
2810 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2811 Diag(VD->getLocation(),
2812 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2813 << VD;
2814 return ExprError();
2815 }
2816 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2817 // A threadprivate directive for static block-scope variables must appear
2818 // in the scope of the variable and not in a nested scope.
2819 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2820 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2821 Diag(Id.getLoc(), diag::err_omp_var_scope)
2822 << getOpenMPDirectiveName(Kind) << VD;
2823 bool IsDecl =
2824 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2825 Diag(VD->getLocation(),
2826 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2827 << VD;
2828 return ExprError();
2829 }
2830
2831 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2832 // A threadprivate directive must lexically precede all references to any
2833 // of the variables in its list.
2834 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2835 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2836 Diag(Id.getLoc(), diag::err_omp_var_used)
2837 << getOpenMPDirectiveName(Kind) << VD;
2838 return ExprError();
2839 }
2840
2841 QualType ExprType = VD->getType().getNonReferenceType();
2842 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2843 SourceLocation(), VD,
2844 /*RefersToEnclosingVariableOrCapture=*/false,
2845 Id.getLoc(), ExprType, VK_LValue);
2846}
2847
2848Sema::DeclGroupPtrTy
2849Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2850 ArrayRef<Expr *> VarList) {
2851 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2852 CurContext->addDecl(D);
2853 return DeclGroupPtrTy::make(DeclGroupRef(D));
2854 }
2855 return nullptr;
2856}
2857
2858namespace {
2859class LocalVarRefChecker final
2860 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2861 Sema &SemaRef;
2862
2863public:
2864 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2865 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2866 if (VD->hasLocalStorage()) {
2867 SemaRef.Diag(E->getBeginLoc(),
2868 diag::err_omp_local_var_in_threadprivate_init)
2869 << E->getSourceRange();
2870 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2871 << VD << VD->getSourceRange();
2872 return true;
2873 }
2874 }
2875 return false;
2876 }
2877 bool VisitStmt(const Stmt *S) {
2878 for (const Stmt *Child : S->children()) {
2879 if (Child && Visit(Child))
2880 return true;
2881 }
2882 return false;
2883 }
2884 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2885};
2886} // namespace
2887
2888OMPThreadPrivateDecl *
2889Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2890 SmallVector<Expr *, 8> Vars;
2891 for (Expr *RefExpr : VarList) {
2892 auto *DE = cast<DeclRefExpr>(RefExpr);
2893 auto *VD = cast<VarDecl>(DE->getDecl());
2894 SourceLocation ILoc = DE->getExprLoc();
2895
2896 // Mark variable as used.
2897 VD->setReferenced();
2898 VD->markUsed(Context);
2899
2900 QualType QType = VD->getType();
2901 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2902 // It will be analyzed later.
2903 Vars.push_back(DE);
2904 continue;
2905 }
2906
2907 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2908 // A threadprivate variable must not have an incomplete type.
2909 if (RequireCompleteType(ILoc, VD->getType(),
2910 diag::err_omp_threadprivate_incomplete_type)) {
2911 continue;
2912 }
2913
2914 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2915 // A threadprivate variable must not have a reference type.
2916 if (VD->getType()->isReferenceType()) {
2917 Diag(ILoc, diag::err_omp_ref_type_arg)
2918 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2919 bool IsDecl =
2920 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2921 Diag(VD->getLocation(),
2922 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2923 << VD;
2924 continue;
2925 }
2926
2927 // Check if this is a TLS variable. If TLS is not being supported, produce
2928 // the corresponding diagnostic.
2929 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2930 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2931 getLangOpts().OpenMPUseTLS &&
2932 getASTContext().getTargetInfo().isTLSSupported())) ||
2933 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2934 !VD->isLocalVarDecl())) {
2935 Diag(ILoc, diag::err_omp_var_thread_local)
2936 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2937 bool IsDecl =
2938 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2939 Diag(VD->getLocation(),
2940 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2941 << VD;
2942 continue;
2943 }
2944
2945 // Check if initial value of threadprivate variable reference variable with
2946 // local storage (it is not supported by runtime).
2947 if (const Expr *Init = VD->getAnyInitializer()) {
2948 LocalVarRefChecker Checker(*this);
2949 if (Checker.Visit(Init))
2950 continue;
2951 }
2952
2953 Vars.push_back(RefExpr);
2954 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
2955 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2956 Context, SourceRange(Loc, Loc)));
2957 if (ASTMutationListener *ML = Context.getASTMutationListener())
2958 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2959 }
2960 OMPThreadPrivateDecl *D = nullptr;
2961 if (!Vars.empty()) {
2962 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2963 Vars);
2964 D->setAccess(AS_public);
2965 }
2966 return D;
2967}
2968
2969static OMPAllocateDeclAttr::AllocatorTypeTy
2970getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2971 if (!Allocator)
2972 return OMPAllocateDeclAttr::OMPNullMemAlloc;
2973 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2974 Allocator->isInstantiationDependent() ||
2975 Allocator->containsUnexpandedParameterPack())
2976 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2977 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2978 const Expr *AE = Allocator->IgnoreParenImpCasts();
2979 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2980 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2981 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2982 llvm::FoldingSetNodeID AEId, DAEId;
2983 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2984 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2985 if (AEId == DAEId) {
2986 AllocatorKindRes = AllocatorKind;
2987 break;
2988 }
2989 }
2990 return AllocatorKindRes;
2991}
2992
2993static bool checkPreviousOMPAllocateAttribute(
2994 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2995 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2996 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2997 return false;
2998 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2999 Expr *PrevAllocator = A->getAllocator();
3000 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3001 getAllocatorKind(S, Stack, PrevAllocator);
3002 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3003 if (AllocatorsMatch &&
3004 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3005 Allocator && PrevAllocator) {
3006 const Expr *AE = Allocator->IgnoreParenImpCasts();
3007 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3008 llvm::FoldingSetNodeID AEId, PAEId;
3009 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3010 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3011 AllocatorsMatch = AEId == PAEId;
3012 }
3013 if (!AllocatorsMatch) {
3014 SmallString<256> AllocatorBuffer;
3015 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3016 if (Allocator)
3017 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3018 SmallString<256> PrevAllocatorBuffer;
3019 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3020 if (PrevAllocator)
3021 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3022 S.getPrintingPolicy());
3023
3024 SourceLocation AllocatorLoc =
3025 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3026 SourceRange AllocatorRange =
3027 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3028 SourceLocation PrevAllocatorLoc =
3029 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3030 SourceRange PrevAllocatorRange =
3031 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3032 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3033 << (Allocator ? 1 : 0) << AllocatorStream.str()
3034 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3035 << AllocatorRange;
3036 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3037 << PrevAllocatorRange;
3038 return true;
3039 }
3040 return false;
3041}
3042
3043static void
3044applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3045 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3046 Expr *Allocator, SourceRange SR) {
3047 if (VD->hasAttr<OMPAllocateDeclAttr>())
3048 return;
3049 if (Allocator &&
3050 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3051 Allocator->isInstantiationDependent() ||
3052 Allocator->containsUnexpandedParameterPack()))
3053 return;
3054 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3055 Allocator, SR);
3056 VD->addAttr(A);
3057 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3058 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3059}
3060
3061Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3062 SourceLocation Loc, ArrayRef<Expr *> VarList,
3063 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3064 assert(Clauses.size() <= 1 && "Expected at most one clause.")((Clauses.size() <= 1 && "Expected at most one clause."
) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Expected at most one clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 3064, __PRETTY_FUNCTION__))
;
3065 Expr *Allocator = nullptr;
3066 if (Clauses.empty()) {
3067 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3068 // allocate directives that appear in a target region must specify an
3069 // allocator clause unless a requires directive with the dynamic_allocators
3070 // clause is present in the same compilation unit.
3071 if (LangOpts.OpenMPIsDevice &&
3072 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3073 targetDiag(Loc, diag::err_expected_allocator_clause);
3074 } else {
3075 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3076 }
3077 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3078 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
3079 SmallVector<Expr *, 8> Vars;
3080 for (Expr *RefExpr : VarList) {
3081 auto *DE = cast<DeclRefExpr>(RefExpr);
3082 auto *VD = cast<VarDecl>(DE->getDecl());
3083
3084 // Check if this is a TLS variable or global register.
3085 if (VD->getTLSKind() != VarDecl::TLS_None ||
3086 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3087 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3088 !VD->isLocalVarDecl()))
3089 continue;
3090
3091 // If the used several times in the allocate directive, the same allocator
3092 // must be used.
3093 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
3094 AllocatorKind, Allocator))
3095 continue;
3096
3097 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3098 // If a list item has a static storage type, the allocator expression in the
3099 // allocator clause must be a constant expression that evaluates to one of
3100 // the predefined memory allocator values.
3101 if (Allocator && VD->hasGlobalStorage()) {
3102 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3103 Diag(Allocator->getExprLoc(),
3104 diag::err_omp_expected_predefined_allocator)
3105 << Allocator->getSourceRange();
3106 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3107 VarDecl::DeclarationOnly;
3108 Diag(VD->getLocation(),
3109 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3110 << VD;
3111 continue;
3112 }
3113 }
3114
3115 Vars.push_back(RefExpr);
3116 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3117 DE->getSourceRange());
3118 }
3119 if (Vars.empty())
3120 return nullptr;
3121 if (!Owner)
3122 Owner = getCurLexicalContext();
3123 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3124 D->setAccess(AS_public);
3125 Owner->addDecl(D);
3126 return DeclGroupPtrTy::make(DeclGroupRef(D));
3127}
3128
3129Sema::DeclGroupPtrTy
3130Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3131 ArrayRef<OMPClause *> ClauseList) {
3132 OMPRequiresDecl *D = nullptr;
3133 if (!CurContext->isFileContext()) {
3134 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3135 } else {
3136 D = CheckOMPRequiresDecl(Loc, ClauseList);
3137 if (D) {
3138 CurContext->addDecl(D);
3139 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
3140 }
3141 }
3142 return DeclGroupPtrTy::make(DeclGroupRef(D));
3143}
3144
3145OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3146 ArrayRef<OMPClause *> ClauseList) {
3147 /// For target specific clauses, the requires directive cannot be
3148 /// specified after the handling of any of the target regions in the
3149 /// current compilation unit.
3150 ArrayRef<SourceLocation> TargetLocations =
3151 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
3152 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
3153 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3154 for (const OMPClause *CNew : ClauseList) {
3155 // Check if any of the requires clauses affect target regions.
3156 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3157 isa<OMPUnifiedAddressClause>(CNew) ||
3158 isa<OMPReverseOffloadClause>(CNew) ||
3159 isa<OMPDynamicAllocatorsClause>(CNew)) {
3160 Diag(Loc, diag::err_omp_directive_before_requires)
3161 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3162 for (SourceLocation TargetLoc : TargetLocations) {
3163 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3164 << "target";
3165 }
3166 } else if (!AtomicLoc.isInvalid() &&
3167 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3168 Diag(Loc, diag::err_omp_directive_before_requires)
3169 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3170 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3171 << "atomic";
3172 }
3173 }
3174 }
3175
3176 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
3177 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3178 ClauseList);
3179 return nullptr;
3180}
3181
3182static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3183 const ValueDecl *D,
3184 const DSAStackTy::DSAVarData &DVar,
3185 bool IsLoopIterVar) {
3186 if (DVar.RefExpr) {
3187 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3188 << getOpenMPClauseName(DVar.CKind);
3189 return;
3190 }
3191 enum {
3192 PDSA_StaticMemberShared,
3193 PDSA_StaticLocalVarShared,
3194 PDSA_LoopIterVarPrivate,
3195 PDSA_LoopIterVarLinear,
3196 PDSA_LoopIterVarLastprivate,
3197 PDSA_ConstVarShared,
3198 PDSA_GlobalVarShared,
3199 PDSA_TaskVarFirstprivate,
3200 PDSA_LocalVarPrivate,
3201 PDSA_Implicit
3202 } Reason = PDSA_Implicit;
3203 bool ReportHint = false;
3204 auto ReportLoc = D->getLocation();
3205 auto *VD = dyn_cast<VarDecl>(D);
3206 if (IsLoopIterVar) {
3207 if (DVar.CKind == OMPC_private)
3208 Reason = PDSA_LoopIterVarPrivate;
3209 else if (DVar.CKind == OMPC_lastprivate)
3210 Reason = PDSA_LoopIterVarLastprivate;
3211 else
3212 Reason = PDSA_LoopIterVarLinear;
3213 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3214 DVar.CKind == OMPC_firstprivate) {
3215 Reason = PDSA_TaskVarFirstprivate;
3216 ReportLoc = DVar.ImplicitDSALoc;
3217 } else if (VD && VD->isStaticLocal())
3218 Reason = PDSA_StaticLocalVarShared;
3219 else if (VD && VD->isStaticDataMember())
3220 Reason = PDSA_StaticMemberShared;
3221 else if (VD && VD->isFileVarDecl())
3222 Reason = PDSA_GlobalVarShared;
3223 else if (D->getType().isConstant(SemaRef.getASTContext()))
3224 Reason = PDSA_ConstVarShared;
3225 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3226 ReportHint = true;
3227 Reason = PDSA_LocalVarPrivate;
3228 }
3229 if (Reason != PDSA_Implicit) {
3230 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3231 << Reason << ReportHint
3232 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3233 } else if (DVar.ImplicitDSALoc.isValid()) {
3234 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3235 << getOpenMPClauseName(DVar.CKind);
3236 }
3237}
3238
3239static OpenMPMapClauseKind
3240getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3241 bool IsAggregateOrDeclareTarget) {
3242 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3243 switch (M) {
3244 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3245 Kind = OMPC_MAP_alloc;
3246 break;
3247 case OMPC_DEFAULTMAP_MODIFIER_to:
3248 Kind = OMPC_MAP_to;
3249 break;
3250 case OMPC_DEFAULTMAP_MODIFIER_from:
3251 Kind = OMPC_MAP_from;
3252 break;
3253 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3254 Kind = OMPC_MAP_tofrom;
3255 break;
3256 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3257 case OMPC_DEFAULTMAP_MODIFIER_last:
3258 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 3258)
;
3259 case OMPC_DEFAULTMAP_MODIFIER_none:
3260 case OMPC_DEFAULTMAP_MODIFIER_default:
3261 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3262 // IsAggregateOrDeclareTarget could be true if:
3263 // 1. the implicit behavior for aggregate is tofrom
3264 // 2. it's a declare target link
3265 if (IsAggregateOrDeclareTarget) {
3266 Kind = OMPC_MAP_tofrom;
3267 break;
3268 }
3269 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 3269)
;
3270 }
3271 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known")((Kind != OMPC_MAP_unknown && "Expect map kind to be known"
) ? static_cast<void> (0) : __assert_fail ("Kind != OMPC_MAP_unknown && \"Expect map kind to be known\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 3271, __PRETTY_FUNCTION__))
;
3272 return Kind;
3273}
3274
3275namespace {
3276class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3277 DSAStackTy *Stack;
3278 Sema &SemaRef;
3279 bool ErrorFound = false;
3280 bool TryCaptureCXXThisMembers = false;
3281 CapturedStmt *CS = nullptr;
3282 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3283 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3284 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3285 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3286
3287 void VisitSubCaptures(OMPExecutableDirective *S) {
3288 // Check implicitly captured variables.
3289 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3290 return;
3291 visitSubCaptures(S->getInnermostCapturedStmt());
3292 // Try to capture inner this->member references to generate correct mappings
3293 // and diagnostics.
3294 if (TryCaptureCXXThisMembers ||
3295 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3296 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3297 [](const CapturedStmt::Capture &C) {
3298 return C.capturesThis();
3299 }))) {
3300 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3301 TryCaptureCXXThisMembers = true;
3302 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3303 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3304 }
3305 // In tasks firstprivates are not captured anymore, need to analyze them
3306 // explicitly.
3307 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3308 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3309 for (OMPClause *C : S->clauses())
3310 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3311 for (Expr *Ref : FC->varlists())
3312 Visit(Ref);
3313 }
3314 }
3315 }
3316
3317public:
3318 void VisitDeclRefExpr(DeclRefExpr *E) {
3319 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3320 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3321 E->isInstantiationDependent())
3322 return;
3323 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3324 // Check the datasharing rules for the expressions in the clauses.
3325 if (!CS) {
3326 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3327 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3328 Visit(CED->getInit());
3329 return;
3330 }
3331 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3332 // Do not analyze internal variables and do not enclose them into
3333 // implicit clauses.
3334 return;
3335 VD = VD->getCanonicalDecl();
3336 // Skip internally declared variables.
3337 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3338 !Stack->isImplicitTaskFirstprivate(VD))
3339 return;
3340 // Skip allocators in uses_allocators clauses.
3341 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3342 return;
3343
3344 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3345 // Check if the variable has explicit DSA set and stop analysis if it so.
3346 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3347 return;
3348
3349 // Skip internally declared static variables.
3350 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3351 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3352 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3353 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3354 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3355 !Stack->isImplicitTaskFirstprivate(VD))
3356 return;
3357
3358 SourceLocation ELoc = E->getExprLoc();
3359 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3360 // The default(none) clause requires that each variable that is referenced
3361 // in the construct, and does not have a predetermined data-sharing
3362 // attribute, must have its data-sharing attribute explicitly determined
3363 // by being listed in a data-sharing attribute clause.
3364 if (DVar.CKind == OMPC_unknown &&
3365 (Stack->getDefaultDSA() == DSA_none ||
3366 Stack->getDefaultDSA() == DSA_firstprivate) &&
3367 isImplicitOrExplicitTaskingRegion(DKind) &&
3368 VarsWithInheritedDSA.count(VD) == 0) {
3369 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3370 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3371 DSAStackTy::DSAVarData DVar =
3372 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3373 InheritedDSA = DVar.CKind == OMPC_unknown;
3374 }
3375 if (InheritedDSA)
3376 VarsWithInheritedDSA[VD] = E;
3377 return;
3378 }
3379
3380 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3381 // If implicit-behavior is none, each variable referenced in the
3382 // construct that does not have a predetermined data-sharing attribute
3383 // and does not appear in a to or link clause on a declare target
3384 // directive must be listed in a data-mapping attribute clause, a
3385 // data-haring attribute clause (including a data-sharing attribute
3386 // clause on a combined construct where target. is one of the
3387 // constituent constructs), or an is_device_ptr clause.
3388 OpenMPDefaultmapClauseKind ClauseKind =
3389 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3390 if (SemaRef.getLangOpts().OpenMP >= 50) {
3391 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3392 OMPC_DEFAULTMAP_MODIFIER_none;
3393 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3394 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3395 // Only check for data-mapping attribute and is_device_ptr here
3396 // since we have already make sure that the declaration does not
3397 // have a data-sharing attribute above
3398 if (!Stack->checkMappableExprComponentListsForDecl(
3399 VD, /*CurrentRegionOnly=*/true,
3400 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3401 MapExprComponents,
3402 OpenMPClauseKind) {
3403 auto MI = MapExprComponents.rbegin();
3404 auto ME = MapExprComponents.rend();
3405 return MI != ME && MI->getAssociatedDeclaration() == VD;
3406 })) {
3407 VarsWithInheritedDSA[VD] = E;
3408 return;
3409 }
3410 }
3411 }
3412
3413 if (isOpenMPTargetExecutionDirective(DKind) &&
3414 !Stack->isLoopControlVariable(VD).first) {
3415 if (!Stack->checkMappableExprComponentListsForDecl(
3416 VD, /*CurrentRegionOnly=*/true,
3417 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3418 StackComponents,
3419 OpenMPClauseKind) {
3420 // Variable is used if it has been marked as an array, array
3421 // section, array shaping or the variable iself.
3422 return StackComponents.size() == 1 ||
3423 std::all_of(
3424 std::next(StackComponents.rbegin()),
3425 StackComponents.rend(),
3426 [](const OMPClauseMappableExprCommon::
3427 MappableComponent &MC) {
3428 return MC.getAssociatedDeclaration() ==
3429 nullptr &&
3430 (isa<OMPArraySectionExpr>(
3431 MC.getAssociatedExpression()) ||
3432 isa<OMPArrayShapingExpr>(
3433 MC.getAssociatedExpression()) ||
3434 isa<ArraySubscriptExpr>(
3435 MC.getAssociatedExpression()));
3436 });
3437 })) {
3438 bool IsFirstprivate = false;
3439 // By default lambdas are captured as firstprivates.
3440 if (const auto *RD =
3441 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3442 IsFirstprivate = RD->isLambda();
3443 IsFirstprivate =
3444 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3445 if (IsFirstprivate) {
3446 ImplicitFirstprivate.emplace_back(E);
3447 } else {
3448 OpenMPDefaultmapClauseModifier M =
3449 Stack->getDefaultmapModifier(ClauseKind);
3450 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3451 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3452 ImplicitMap[Kind].emplace_back(E);
3453 }
3454 return;
3455 }
3456 }
3457
3458 // OpenMP [2.9.3.6, Restrictions, p.2]
3459 // A list item that appears in a reduction clause of the innermost
3460 // enclosing worksharing or parallel construct may not be accessed in an
3461 // explicit task.
3462 DVar = Stack->hasInnermostDSA(
3463 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3464 [](OpenMPDirectiveKind K) {
3465 return isOpenMPParallelDirective(K) ||
3466 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3467 },
3468 /*FromParent=*/true);
3469 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3470 ErrorFound = true;
3471 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3472 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3473 return;
3474 }
3475
3476 // Define implicit data-sharing attributes for task.
3477 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3478 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3479 (Stack->getDefaultDSA() == DSA_firstprivate &&
3480 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3481 !Stack->isLoopControlVariable(VD).first) {
3482 ImplicitFirstprivate.push_back(E);
3483 return;
3484 }
3485
3486 // Store implicitly used globals with declare target link for parent
3487 // target.
3488 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3489 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3490 Stack->addToParentTargetRegionLinkGlobals(E);
3491 return;
3492 }
3493 }
3494 }
3495 void VisitMemberExpr(MemberExpr *E) {
3496 if (E->isTypeDependent() || E->isValueDependent() ||
3497 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3498 return;
3499 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3500 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3501 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3502 if (!FD)
3503 return;
3504 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3505 // Check if the variable has explicit DSA set and stop analysis if it
3506 // so.
3507 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3508 return;
3509
3510 if (isOpenMPTargetExecutionDirective(DKind) &&
3511 !Stack->isLoopControlVariable(FD).first &&
3512 !Stack->checkMappableExprComponentListsForDecl(
3513 FD, /*CurrentRegionOnly=*/true,
3514 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3515 StackComponents,
3516 OpenMPClauseKind) {
3517 return isa<CXXThisExpr>(
3518 cast<MemberExpr>(
3519 StackComponents.back().getAssociatedExpression())
3520 ->getBase()
3521 ->IgnoreParens());
3522 })) {
3523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3524 // A bit-field cannot appear in a map clause.
3525 //
3526 if (FD->isBitField())
3527 return;
3528
3529 // Check to see if the member expression is referencing a class that
3530 // has already been explicitly mapped
3531 if (Stack->isClassPreviouslyMapped(TE->getType()))
3532 return;
3533
3534 OpenMPDefaultmapClauseModifier Modifier =
3535 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3536 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3537 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3538 ImplicitMap[Kind].emplace_back(E);
3539 return;
3540 }
3541
3542 SourceLocation ELoc = E->getExprLoc();
3543 // OpenMP [2.9.3.6, Restrictions, p.2]
3544 // A list item that appears in a reduction clause of the innermost
3545 // enclosing worksharing or parallel construct may not be accessed in
3546 // an explicit task.
3547 DVar = Stack->hasInnermostDSA(
3548 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3549 [](OpenMPDirectiveKind K) {
3550 return isOpenMPParallelDirective(K) ||
3551 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3552 },
3553 /*FromParent=*/true);
3554 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3555 ErrorFound = true;
3556 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3557 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3558 return;
3559 }
3560
3561 // Define implicit data-sharing attributes for task.
3562 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3563 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3564 !Stack->isLoopControlVariable(FD).first) {
3565 // Check if there is a captured expression for the current field in the
3566 // region. Do not mark it as firstprivate unless there is no captured
3567 // expression.
3568 // TODO: try to make it firstprivate.
3569 if (DVar.CKind != OMPC_unknown)
3570 ImplicitFirstprivate.push_back(E);
3571 }
3572 return;
3573 }
3574 if (isOpenMPTargetExecutionDirective(DKind)) {
3575 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3576 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3577 /*NoDiagnose=*/true))
3578 return;
3579 const auto *VD = cast<ValueDecl>(
3580 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3581 if (!Stack->checkMappableExprComponentListsForDecl(
3582 VD, /*CurrentRegionOnly=*/true,
3583 [&CurComponents](
3584 OMPClauseMappableExprCommon::MappableExprComponentListRef
3585 StackComponents,
3586 OpenMPClauseKind) {
3587 auto CCI = CurComponents.rbegin();
3588 auto CCE = CurComponents.rend();
3589 for (const auto &SC : llvm::reverse(StackComponents)) {
3590 // Do both expressions have the same kind?
3591 if (CCI->getAssociatedExpression()->getStmtClass() !=
3592 SC.getAssociatedExpression()->getStmtClass())
3593 if (!((isa<OMPArraySectionExpr>(
3594 SC.getAssociatedExpression()) ||
3595 isa<OMPArrayShapingExpr>(
3596 SC.getAssociatedExpression())) &&
3597 isa<ArraySubscriptExpr>(
3598 CCI->getAssociatedExpression())))
3599 return false;
3600
3601 const Decl *CCD = CCI->getAssociatedDeclaration();
3602 const Decl *SCD = SC.getAssociatedDeclaration();
3603 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3604 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3605 if (SCD != CCD)
3606 return false;
3607 std::advance(CCI, 1);
3608 if (CCI == CCE)
3609 break;
3610 }
3611 return true;
3612 })) {
3613 Visit(E->getBase());
3614 }
3615 } else if (!TryCaptureCXXThisMembers) {
3616 Visit(E->getBase());
3617 }
3618 }
3619 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3620 for (OMPClause *C : S->clauses()) {
3621 // Skip analysis of arguments of implicitly defined firstprivate clause
3622 // for task|target directives.
3623 // Skip analysis of arguments of implicitly defined map clause for target
3624 // directives.
3625 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3626 C->isImplicit())) {
3627 for (Stmt *CC : C->children()) {
3628 if (CC)
3629 Visit(CC);
3630 }
3631 }
3632 }
3633 // Check implicitly captured variables.
3634 VisitSubCaptures(S);
3635 }
3636 void VisitStmt(Stmt *S) {
3637 for (Stmt *C : S->children()) {
3638 if (C) {
3639 // Check implicitly captured variables in the task-based directives to
3640 // check if they must be firstprivatized.
3641 Visit(C);
3642 }
3643 }
3644 }
3645
3646 void visitSubCaptures(CapturedStmt *S) {
3647 for (const CapturedStmt::Capture &Cap : S->captures()) {
3648 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3649 continue;
3650 VarDecl *VD = Cap.getCapturedVar();
3651 // Do not try to map the variable if it or its sub-component was mapped
3652 // already.
3653 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3654 Stack->checkMappableExprComponentListsForDecl(
3655 VD, /*CurrentRegionOnly=*/true,
3656 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3657 OpenMPClauseKind) { return true; }))
3658 continue;
3659 DeclRefExpr *DRE = buildDeclRefExpr(
3660 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3661 Cap.getLocation(), /*RefersToCapture=*/true);
3662 Visit(DRE);
3663 }
3664 }
3665 bool isErrorFound() const { return ErrorFound; }
3666 ArrayRef<Expr *> getImplicitFirstprivate() const {
3667 return ImplicitFirstprivate;
3668 }
3669 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3670 return ImplicitMap[Kind];
3671 }
3672 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3673 return VarsWithInheritedDSA;
3674 }
3675
3676 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3677 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3678 // Process declare target link variables for the target directives.
3679 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3680 for (DeclRefExpr *E : Stack->getLinkGlobals())
3681 Visit(E);
3682 }
3683 }
3684};
3685} // namespace
3686
3687void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3688 switch (DKind) {
3689 case OMPD_parallel:
3690 case OMPD_parallel_for:
3691 case OMPD_parallel_for_simd:
3692 case OMPD_parallel_sections:
3693 case OMPD_parallel_master:
3694 case OMPD_teams:
3695 case OMPD_teams_distribute:
3696 case OMPD_teams_distribute_simd: {
3697 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3698 QualType KmpInt32PtrTy =
3699 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3700 Sema::CapturedParamNameType Params[] = {
3701 std::make_pair(".global_tid.", KmpInt32PtrTy),
3702 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3703 std::make_pair(StringRef(), QualType()) // __context with shared vars
3704 };
3705 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3706 Params);
3707 break;
3708 }
3709 case OMPD_target_teams:
3710 case OMPD_target_parallel:
3711 case OMPD_target_parallel_for:
3712 case OMPD_target_parallel_for_simd:
3713 case OMPD_target_teams_distribute:
3714 case OMPD_target_teams_distribute_simd: {
3715 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3716 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3717 QualType KmpInt32PtrTy =
3718 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3719 QualType Args[] = {VoidPtrTy};
3720 FunctionProtoType::ExtProtoInfo EPI;
3721 EPI.Variadic = true;
3722 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3723 Sema::CapturedParamNameType Params[] = {
3724 std::make_pair(".global_tid.", KmpInt32Ty),
3725 std::make_pair(".part_id.", KmpInt32PtrTy),
3726 std::make_pair(".privates.", VoidPtrTy),
3727 std::make_pair(
3728 ".copy_fn.",
3729 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3730 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3731 std::make_pair(StringRef(), QualType()) // __context with shared vars
3732 };
3733 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3734 Params, /*OpenMPCaptureLevel=*/0);
3735 // Mark this captured region as inlined, because we don't use outlined
3736 // function directly.
3737 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3738 AlwaysInlineAttr::CreateImplicit(
3739 Context, {}, AttributeCommonInfo::AS_Keyword,
3740 AlwaysInlineAttr::Keyword_forceinline));
3741 Sema::CapturedParamNameType ParamsTarget[] = {
3742 std::make_pair(StringRef(), QualType()) // __context with shared vars
3743 };
3744 // Start a captured region for 'target' with no implicit parameters.
3745 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3746 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3747 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3748 std::make_pair(".global_tid.", KmpInt32PtrTy),
3749 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3750 std::make_pair(StringRef(), QualType()) // __context with shared vars
3751 };
3752 // Start a captured region for 'teams' or 'parallel'. Both regions have
3753 // the same implicit parameters.
3754 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3755 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3756 break;
3757 }
3758 case OMPD_target:
3759 case OMPD_target_simd: {
3760 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3761 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3762 QualType KmpInt32PtrTy =
3763 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3764 QualType Args[] = {VoidPtrTy};
3765 FunctionProtoType::ExtProtoInfo EPI;
3766 EPI.Variadic = true;
3767 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3768 Sema::CapturedParamNameType Params[] = {
3769 std::make_pair(".global_tid.", KmpInt32Ty),
3770 std::make_pair(".part_id.", KmpInt32PtrTy),
3771 std::make_pair(".privates.", VoidPtrTy),
3772 std::make_pair(
3773 ".copy_fn.",
3774 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3775 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3776 std::make_pair(StringRef(), QualType()) // __context with shared vars
3777 };
3778 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3779 Params, /*OpenMPCaptureLevel=*/0);
3780 // Mark this captured region as inlined, because we don't use outlined
3781 // function directly.
3782 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3783 AlwaysInlineAttr::CreateImplicit(
3784 Context, {}, AttributeCommonInfo::AS_Keyword,
3785 AlwaysInlineAttr::Keyword_forceinline));
3786 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3787 std::make_pair(StringRef(), QualType()),
3788 /*OpenMPCaptureLevel=*/1);
3789 break;
3790 }
3791 case OMPD_simd:
3792 case OMPD_for:
3793 case OMPD_for_simd:
3794 case OMPD_sections:
3795 case OMPD_section:
3796 case OMPD_single:
3797 case OMPD_master:
3798 case OMPD_critical:
3799 case OMPD_taskgroup:
3800 case OMPD_distribute:
3801 case OMPD_distribute_simd:
3802 case OMPD_ordered:
3803 case OMPD_atomic:
3804 case OMPD_target_data: {
3805 Sema::CapturedParamNameType Params[] = {
3806 std::make_pair(StringRef(), QualType()) // __context with shared vars
3807 };
3808 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3809 Params);
3810 break;
3811 }
3812 case OMPD_task: {
3813 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3814 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3815 QualType KmpInt32PtrTy =
3816 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3817 QualType Args[] = {VoidPtrTy};
3818 FunctionProtoType::ExtProtoInfo EPI;
3819 EPI.Variadic = true;
3820 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3821 Sema::CapturedParamNameType Params[] = {
3822 std::make_pair(".global_tid.", KmpInt32Ty),
3823 std::make_pair(".part_id.", KmpInt32PtrTy),
3824 std::make_pair(".privates.", VoidPtrTy),
3825 std::make_pair(
3826 ".copy_fn.",
3827 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3828 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3829 std::make_pair(StringRef(), QualType()) // __context with shared vars
3830 };
3831 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3832 Params);
3833 // Mark this captured region as inlined, because we don't use outlined
3834 // function directly.
3835 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3836 AlwaysInlineAttr::CreateImplicit(
3837 Context, {}, AttributeCommonInfo::AS_Keyword,
3838 AlwaysInlineAttr::Keyword_forceinline));
3839 break;
3840 }
3841 case OMPD_taskloop:
3842 case OMPD_taskloop_simd:
3843 case OMPD_master_taskloop:
3844 case OMPD_master_taskloop_simd: {
3845 QualType KmpInt32Ty =
3846 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3847 .withConst();
3848 QualType KmpUInt64Ty =
3849 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3850 .withConst();
3851 QualType KmpInt64Ty =
3852 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3853 .withConst();
3854 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3855 QualType KmpInt32PtrTy =
3856 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3857 QualType Args[] = {VoidPtrTy};
3858 FunctionProtoType::ExtProtoInfo EPI;
3859 EPI.Variadic = true;
3860 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3861 Sema::CapturedParamNameType Params[] = {
3862 std::make_pair(".global_tid.", KmpInt32Ty),
3863 std::make_pair(".part_id.", KmpInt32PtrTy),
3864 std::make_pair(".privates.", VoidPtrTy),
3865 std::make_pair(
3866 ".copy_fn.",
3867 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3868 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3869 std::make_pair(".lb.", KmpUInt64Ty),
3870 std::make_pair(".ub.", KmpUInt64Ty),
3871 std::make_pair(".st.", KmpInt64Ty),
3872 std::make_pair(".liter.", KmpInt32Ty),
3873 std::make_pair(".reductions.", VoidPtrTy),
3874 std::make_pair(StringRef(), QualType()) // __context with shared vars
3875 };
3876 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3877 Params);
3878 // Mark this captured region as inlined, because we don't use outlined
3879 // function directly.
3880 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3881 AlwaysInlineAttr::CreateImplicit(
3882 Context, {}, AttributeCommonInfo::AS_Keyword,
3883 AlwaysInlineAttr::Keyword_forceinline));
3884 break;
3885 }
3886 case OMPD_parallel_master_taskloop:
3887 case OMPD_parallel_master_taskloop_simd: {
3888 QualType KmpInt32Ty =
3889 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3890 .withConst();
3891 QualType KmpUInt64Ty =
3892 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3893 .withConst();
3894 QualType KmpInt64Ty =
3895 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3896 .withConst();
3897 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3898 QualType KmpInt32PtrTy =
3899 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3900 Sema::CapturedParamNameType ParamsParallel[] = {
3901 std::make_pair(".global_tid.", KmpInt32PtrTy),
3902 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3903 std::make_pair(StringRef(), QualType()) // __context with shared vars
3904 };
3905 // Start a captured region for 'parallel'.
3906 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3907 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3908 QualType Args[] = {VoidPtrTy};
3909 FunctionProtoType::ExtProtoInfo EPI;
3910 EPI.Variadic = true;
3911 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3912 Sema::CapturedParamNameType Params[] = {
3913 std::make_pair(".global_tid.", KmpInt32Ty),
3914 std::make_pair(".part_id.", KmpInt32PtrTy),
3915 std::make_pair(".privates.", VoidPtrTy),
3916 std::make_pair(
3917 ".copy_fn.",
3918 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3919 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3920 std::make_pair(".lb.", KmpUInt64Ty),
3921 std::make_pair(".ub.", KmpUInt64Ty),
3922 std::make_pair(".st.", KmpInt64Ty),
3923 std::make_pair(".liter.", KmpInt32Ty),
3924 std::make_pair(".reductions.", VoidPtrTy),
3925 std::make_pair(StringRef(), QualType()) // __context with shared vars
3926 };
3927 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3928 Params, /*OpenMPCaptureLevel=*/1);
3929 // Mark this captured region as inlined, because we don't use outlined
3930 // function directly.
3931 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3932 AlwaysInlineAttr::CreateImplicit(
3933 Context, {}, AttributeCommonInfo::AS_Keyword,
3934 AlwaysInlineAttr::Keyword_forceinline));
3935 break;
3936 }
3937 case OMPD_distribute_parallel_for_simd:
3938 case OMPD_distribute_parallel_for: {
3939 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3940 QualType KmpInt32PtrTy =
3941 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3942 Sema::CapturedParamNameType Params[] = {
3943 std::make_pair(".global_tid.", KmpInt32PtrTy),
3944 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3945 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3946 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3947 std::make_pair(StringRef(), QualType()) // __context with shared vars
3948 };
3949 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3950 Params);
3951 break;
3952 }
3953 case OMPD_target_teams_distribute_parallel_for:
3954 case OMPD_target_teams_distribute_parallel_for_simd: {
3955 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3956 QualType KmpInt32PtrTy =
3957 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3958 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3959
3960 QualType Args[] = {VoidPtrTy};
3961 FunctionProtoType::ExtProtoInfo EPI;
3962 EPI.Variadic = true;
3963 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3964 Sema::CapturedParamNameType Params[] = {
3965 std::make_pair(".global_tid.", KmpInt32Ty),
3966 std::make_pair(".part_id.", KmpInt32PtrTy),
3967 std::make_pair(".privates.", VoidPtrTy),
3968 std::make_pair(
3969 ".copy_fn.",
3970 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3971 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3972 std::make_pair(StringRef(), QualType()) // __context with shared vars
3973 };
3974 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3975 Params, /*OpenMPCaptureLevel=*/0);
3976 // Mark this captured region as inlined, because we don't use outlined
3977 // function directly.
3978 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3979 AlwaysInlineAttr::CreateImplicit(
3980 Context, {}, AttributeCommonInfo::AS_Keyword,
3981 AlwaysInlineAttr::Keyword_forceinline));
3982 Sema::CapturedParamNameType ParamsTarget[] = {
3983 std::make_pair(StringRef(), QualType()) // __context with shared vars
3984 };
3985 // Start a captured region for 'target' with no implicit parameters.
3986 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3987 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3988
3989 Sema::CapturedParamNameType ParamsTeams[] = {
3990 std::make_pair(".global_tid.", KmpInt32PtrTy),
3991 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3992 std::make_pair(StringRef(), QualType()) // __context with shared vars
3993 };
3994 // Start a captured region for 'target' with no implicit parameters.
3995 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3996 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3997
3998 Sema::CapturedParamNameType ParamsParallel[] = {
3999 std::make_pair(".global_tid.", KmpInt32PtrTy),
4000 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4001 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4002 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4003 std::make_pair(StringRef(), QualType()) // __context with shared vars
4004 };
4005 // Start a captured region for 'teams' or 'parallel'. Both regions have
4006 // the same implicit parameters.
4007 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4008 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4009 break;
4010 }
4011
4012 case OMPD_teams_distribute_parallel_for:
4013 case OMPD_teams_distribute_parallel_for_simd: {
4014 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4015 QualType KmpInt32PtrTy =
4016 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4017
4018 Sema::CapturedParamNameType ParamsTeams[] = {
4019 std::make_pair(".global_tid.", KmpInt32PtrTy),
4020 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4021 std::make_pair(StringRef(), QualType()) // __context with shared vars
4022 };
4023 // Start a captured region for 'target' with no implicit parameters.
4024 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4025 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4026
4027 Sema::CapturedParamNameType ParamsParallel[] = {
4028 std::make_pair(".global_tid.", KmpInt32PtrTy),
4029 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4030 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4031 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4032 std::make_pair(StringRef(), QualType()) // __context with shared vars
4033 };
4034 // Start a captured region for 'teams' or 'parallel'. Both regions have
4035 // the same implicit parameters.
4036 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4037 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4038 break;
4039 }
4040 case OMPD_target_update:
4041 case OMPD_target_enter_data:
4042 case OMPD_target_exit_data: {
4043 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4044 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4045 QualType KmpInt32PtrTy =
4046 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4047 QualType Args[] = {VoidPtrTy};
4048 FunctionProtoType::ExtProtoInfo EPI;
4049 EPI.Variadic = true;
4050 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4051 Sema::CapturedParamNameType Params[] = {
4052 std::make_pair(".global_tid.", KmpInt32Ty),
4053 std::make_pair(".part_id.", KmpInt32PtrTy),
4054 std::make_pair(".privates.", VoidPtrTy),
4055 std::make_pair(
4056 ".copy_fn.",
4057 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4058 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4059 std::make_pair(StringRef(), QualType()) // __context with shared vars
4060 };
4061 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
4062 Params);
4063 // Mark this captured region as inlined, because we don't use outlined
4064 // function directly.
4065 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4066 AlwaysInlineAttr::CreateImplicit(
4067 Context, {}, AttributeCommonInfo::AS_Keyword,
4068 AlwaysInlineAttr::Keyword_forceinline));
4069 break;
4070 }
4071 case OMPD_threadprivate:
4072 case OMPD_allocate:
4073 case OMPD_taskyield:
4074 case OMPD_barrier:
4075 case OMPD_taskwait:
4076 case OMPD_cancellation_point:
4077 case OMPD_cancel:
4078 case OMPD_flush:
4079 case OMPD_depobj:
4080 case OMPD_scan:
4081 case OMPD_declare_reduction:
4082 case OMPD_declare_mapper:
4083 case OMPD_declare_simd:
4084 case OMPD_declare_target:
4085 case OMPD_end_declare_target:
4086 case OMPD_requires:
4087 case OMPD_declare_variant:
4088 case OMPD_begin_declare_variant:
4089 case OMPD_end_declare_variant:
4090 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4090)
;
4091 case OMPD_unknown:
4092 default:
4093 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4093)
;
4094 }
4095}
4096
4097int Sema::getNumberOfConstructScopes(unsigned Level) const {
4098 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
4099}
4100
4101int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4102 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4103 getOpenMPCaptureRegions(CaptureRegions, DKind);
4104 return CaptureRegions.size();
4105}
4106
4107static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4108 Expr *CaptureExpr, bool WithInit,
4109 bool AsExpression) {
4110 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4110, __PRETTY_FUNCTION__))
;
4111 ASTContext &C = S.getASTContext();
4112 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4113 QualType Ty = Init->getType();
4114 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4115 if (S.getLangOpts().CPlusPlus) {
4116 Ty = C.getLValueReferenceType(Ty);
4117 } else {
4118 Ty = C.getPointerType(Ty);
4119 ExprResult Res =
4120 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4121 if (!Res.isUsable())
4122 return nullptr;
4123 Init = Res.get();
4124 }
4125 WithInit = true;
4126 }
4127 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4128 CaptureExpr->getBeginLoc());
4129 if (!WithInit)
4130 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4131 S.CurContext->addHiddenDecl(CED);
4132 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4133 return CED;
4134}
4135
4136static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4137 bool WithInit) {
4138 OMPCapturedExprDecl *CD;
4139 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4140 CD = cast<OMPCapturedExprDecl>(VD);
4141 else
4142 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4143 /*AsExpression=*/false);
4144 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4145 CaptureExpr->getExprLoc());
4146}
4147
4148static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4149 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4150 if (!Ref) {
4151 OMPCapturedExprDecl *CD = buildCaptureDecl(
4152 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4153 /*WithInit=*/true, /*AsExpression=*/true);
4154 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4155 CaptureExpr->getExprLoc());
4156 }
4157 ExprResult Res = Ref;
4158 if (!S.getLangOpts().CPlusPlus &&
4159 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4160 Ref->getType()->isPointerType()) {
4161 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4162 if (!Res.isUsable())
4163 return ExprError();
4164 }
4165 return S.DefaultLvalueConversion(Res.get());
4166}
4167
4168namespace {
4169// OpenMP directives parsed in this section are represented as a
4170// CapturedStatement with an associated statement. If a syntax error
4171// is detected during the parsing of the associated statement, the
4172// compiler must abort processing and close the CapturedStatement.
4173//
4174// Combined directives such as 'target parallel' have more than one
4175// nested CapturedStatements. This RAII ensures that we unwind out
4176// of all the nested CapturedStatements when an error is found.
4177class CaptureRegionUnwinderRAII {
4178private:
4179 Sema &S;
4180 bool &ErrorFound;
4181 OpenMPDirectiveKind DKind = OMPD_unknown;
4182
4183public:
4184 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4185 OpenMPDirectiveKind DKind)
4186 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4187 ~CaptureRegionUnwinderRAII() {
4188 if (ErrorFound) {
4189 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4190 while (--ThisCaptureLevel >= 0)
4191 S.ActOnCapturedRegionError();
4192 }
4193 }
4194};
4195} // namespace
4196
4197void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4198 // Capture variables captured by reference in lambdas for target-based
4199 // directives.
4200 if (!CurContext->isDependentContext() &&
4201 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
4202 isOpenMPTargetDataManagementDirective(
4203 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
4204 QualType Type = V->getType();
4205 if (const auto *RD = Type.getCanonicalType()
4206 .getNonReferenceType()
4207 ->getAsCXXRecordDecl()) {
4208 bool SavedForceCaptureByReferenceInTargetExecutable =
4209 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
4210 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4211 /*V=*/true);
4212 if (RD->isLambda()) {
4213 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4214 FieldDecl *ThisCapture;
4215 RD->getCaptureFields(Captures, ThisCapture);
4216 for (const LambdaCapture &LC : RD->captures()) {
4217 if (LC.getCaptureKind() == LCK_ByRef) {
4218 VarDecl *VD = LC.getCapturedVar();
4219 DeclContext *VDC = VD->getDeclContext();
4220 if (!VDC->Encloses(CurContext))
4221 continue;
4222 MarkVariableReferenced(LC.getLocation(), VD);
4223 } else if (LC.getCaptureKind() == LCK_This) {
4224 QualType ThisTy = getCurrentThisType();
4225 if (!ThisTy.isNull() &&
4226 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4227 CheckCXXThisCapture(LC.getLocation());
4228 }
4229 }
4230 }
4231 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
4232 SavedForceCaptureByReferenceInTargetExecutable);
4233 }
4234 }
4235}
4236
4237static bool checkOrderedOrderSpecified(Sema &S,
4238 const ArrayRef<OMPClause *> Clauses) {
4239 const OMPOrderedClause *Ordered = nullptr;
4240 const OMPOrderClause *Order = nullptr;
4241
4242 for (const OMPClause *Clause : Clauses) {
4243 if (Clause->getClauseKind() == OMPC_ordered)
4244 Ordered = cast<OMPOrderedClause>(Clause);
4245 else if (Clause->getClauseKind() == OMPC_order) {
4246 Order = cast<OMPOrderClause>(Clause);
4247 if (Order->getKind() != OMPC_ORDER_concurrent)
4248 Order = nullptr;
4249 }
4250 if (Ordered && Order)
4251 break;
4252 }
4253
4254 if (Ordered && Order) {
4255 S.Diag(Order->getKindKwLoc(),
4256 diag::err_omp_simple_clause_incompatible_with_ordered)
4257 << getOpenMPClauseName(OMPC_order)
4258 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4259 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4260 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4261 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4262 return true;
4263 }
4264 return false;
4265}
4266
4267StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4268 ArrayRef<OMPClause *> Clauses) {
4269 bool ErrorFound = false;
4270 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4271 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4272 if (!S.isUsable()) {
4273 ErrorFound = true;
Value stored to 'ErrorFound' is never read
4274 return StmtError();
4275 }
4276
4277 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4278 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4279 OMPOrderedClause *OC = nullptr;
4280 OMPScheduleClause *SC = nullptr;
4281 SmallVector<const OMPLinearClause *, 4> LCs;
4282 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4283 // This is required for proper codegen.
4284 for (OMPClause *Clause : Clauses) {
4285 if (!LangOpts.OpenMPSimd &&
4286 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4287 Clause->getClauseKind() == OMPC_in_reduction) {
4288 // Capture taskgroup task_reduction descriptors inside the tasking regions
4289 // with the corresponding in_reduction items.
4290 auto *IRC = cast<OMPInReductionClause>(Clause);
4291 for (Expr *E : IRC->taskgroup_descriptors())
4292 if (E)
4293 MarkDeclarationsReferencedInExpr(E);
4294 }
4295 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4296 Clause->getClauseKind() == OMPC_copyprivate ||
4297 (getLangOpts().OpenMPUseTLS &&
4298 getASTContext().getTargetInfo().isTLSSupported() &&
4299 Clause->getClauseKind() == OMPC_copyin)) {
4300 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4301 // Mark all variables in private list clauses as used in inner region.
4302 for (Stmt *VarRef : Clause->children()) {
4303 if (auto *E = cast_or_null<Expr>(VarRef)) {
4304 MarkDeclarationsReferencedInExpr(E);
4305 }
4306 }
4307 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
4308 } else if (CaptureRegions.size() > 1 ||
4309 CaptureRegions.back() != OMPD_unknown) {
4310 if (auto *C = OMPClauseWithPreInit::get(Clause))
4311 PICs.push_back(C);
4312 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4313 if (Expr *E = C->getPostUpdateExpr())
4314 MarkDeclarationsReferencedInExpr(E);
4315 }
4316 }
4317 if (Clause->getClauseKind() == OMPC_schedule)
4318 SC = cast<OMPScheduleClause>(Clause);
4319 else if (Clause->getClauseKind() == OMPC_ordered)
4320 OC = cast<OMPOrderedClause>(Clause);
4321 else if (Clause->getClauseKind() == OMPC_linear)
4322 LCs.push_back(cast<OMPLinearClause>(Clause));
4323 }
4324 // Capture allocator expressions if used.
4325 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
4326 MarkDeclarationsReferencedInExpr(E);
4327 // OpenMP, 2.7.1 Loop Construct, Restrictions
4328 // The nonmonotonic modifier cannot be specified if an ordered clause is
4329 // specified.
4330 if (SC &&
4331 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4332 SC->getSecondScheduleModifier() ==
4333 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4334 OC) {
4335 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4336 ? SC->getFirstScheduleModifierLoc()
4337 : SC->getSecondScheduleModifierLoc(),
4338 diag::err_omp_simple_clause_incompatible_with_ordered)
4339 << getOpenMPClauseName(OMPC_schedule)
4340 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4341 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4342 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4343 ErrorFound = true;
4344 }
4345 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4346 // If an order(concurrent) clause is present, an ordered clause may not appear
4347 // on the same directive.
4348 if (checkOrderedOrderSpecified(*this, Clauses))
4349 ErrorFound = true;
4350 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4351 for (const OMPLinearClause *C : LCs) {
4352 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4353 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4354 }
4355 ErrorFound = true;
4356 }
4357 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4358 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4359 OC->getNumForLoops()) {
4360 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4361 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4362 ErrorFound = true;
4363 }
4364 if (ErrorFound) {
4365 return StmtError();
4366 }
4367 StmtResult SR = S;
4368 unsigned CompletedRegions = 0;
4369 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4370 // Mark all variables in private list clauses as used in inner region.
4371 // Required for proper codegen of combined directives.
4372 // TODO: add processing for other clauses.
4373 if (ThisCaptureRegion != OMPD_unknown) {
4374 for (const clang::OMPClauseWithPreInit *C : PICs) {
4375 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4376 // Find the particular capture region for the clause if the
4377 // directive is a combined one with multiple capture regions.
4378 // If the directive is not a combined one, the capture region
4379 // associated with the clause is OMPD_unknown and is generated
4380 // only once.
4381 if (CaptureRegion == ThisCaptureRegion ||
4382 CaptureRegion == OMPD_unknown) {
4383 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4384 for (Decl *D : DS->decls())
4385 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4386 }
4387 }
4388 }
4389 }
4390 if (ThisCaptureRegion == OMPD_target) {
4391 // Capture allocator traits in the target region. They are used implicitly
4392 // and, thus, are not captured by default.
4393 for (OMPClause *C : Clauses) {
4394 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4395 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4396 ++I) {
4397 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4398 if (Expr *E = D.AllocatorTraits)
4399 MarkDeclarationsReferencedInExpr(E);
4400 }
4401 continue;
4402 }
4403 }
4404 }
4405 if (++CompletedRegions == CaptureRegions.size())
4406 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4407 SR = ActOnCapturedRegionEnd(SR.get());
4408 }
4409 return SR;
4410}
4411
4412static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4413 OpenMPDirectiveKind CancelRegion,
4414 SourceLocation StartLoc) {
4415 // CancelRegion is only needed for cancel and cancellation_point.
4416 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4417 return false;
4418
4419 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4420 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4421 return false;
4422
4423 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4424 << getOpenMPDirectiveName(CancelRegion);
4425 return true;
4426}
4427
4428static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4429 OpenMPDirectiveKind CurrentRegion,
4430 const DeclarationNameInfo &CurrentName,
4431 OpenMPDirectiveKind CancelRegion,
4432 SourceLocation StartLoc) {
4433 if (Stack->getCurScope()) {
4434 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4435 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4436 bool NestingProhibited = false;
4437 bool CloseNesting = true;
4438 bool OrphanSeen = false;
4439 enum {
4440 NoRecommend,
4441 ShouldBeInParallelRegion,
4442 ShouldBeInOrderedRegion,
4443 ShouldBeInTargetRegion,
4444 ShouldBeInTeamsRegion,
4445 ShouldBeInLoopSimdRegion,
4446 } Recommend = NoRecommend;
4447 if (isOpenMPSimdDirective(ParentRegion) &&
4448 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4449 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4450 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4451 CurrentRegion != OMPD_scan))) {
4452 // OpenMP [2.16, Nesting of Regions]
4453 // OpenMP constructs may not be nested inside a simd region.
4454 // OpenMP [2.8.1,simd Construct, Restrictions]
4455 // An ordered construct with the simd clause is the only OpenMP
4456 // construct that can appear in the simd region.
4457 // Allowing a SIMD construct nested in another SIMD construct is an
4458 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4459 // message.
4460 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4461 // The only OpenMP constructs that can be encountered during execution of
4462 // a simd region are the atomic construct, the loop construct, the simd
4463 // construct and the ordered construct with the simd clause.
4464 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4465 ? diag::err_omp_prohibited_region_simd
4466 : diag::warn_omp_nesting_simd)
4467 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4468 return CurrentRegion != OMPD_simd;
4469 }
4470 if (ParentRegion == OMPD_atomic) {
4471 // OpenMP [2.16, Nesting of Regions]
4472 // OpenMP constructs may not be nested inside an atomic region.
4473 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4474 return true;
4475 }
4476 if (CurrentRegion == OMPD_section) {
4477 // OpenMP [2.7.2, sections Construct, Restrictions]
4478 // Orphaned section directives are prohibited. That is, the section
4479 // directives must appear within the sections construct and must not be
4480 // encountered elsewhere in the sections region.
4481 if (ParentRegion != OMPD_sections &&
4482 ParentRegion != OMPD_parallel_sections) {
4483 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4484 << (ParentRegion != OMPD_unknown)
4485 << getOpenMPDirectiveName(ParentRegion);
4486 return true;
4487 }
4488 return false;
4489 }
4490 // Allow some constructs (except teams and cancellation constructs) to be
4491 // orphaned (they could be used in functions, called from OpenMP regions
4492 // with the required preconditions).
4493 if (ParentRegion == OMPD_unknown &&
4494 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4495 CurrentRegion != OMPD_cancellation_point &&
4496 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4497 return false;
4498 if (CurrentRegion == OMPD_cancellation_point ||
4499 CurrentRegion == OMPD_cancel) {
4500 // OpenMP [2.16, Nesting of Regions]
4501 // A cancellation point construct for which construct-type-clause is
4502 // taskgroup must be nested inside a task construct. A cancellation
4503 // point construct for which construct-type-clause is not taskgroup must
4504 // be closely nested inside an OpenMP construct that matches the type
4505 // specified in construct-type-clause.
4506 // A cancel construct for which construct-type-clause is taskgroup must be
4507 // nested inside a task construct. A cancel construct for which
4508 // construct-type-clause is not taskgroup must be closely nested inside an
4509 // OpenMP construct that matches the type specified in
4510 // construct-type-clause.
4511 NestingProhibited =
4512 !((CancelRegion == OMPD_parallel &&
4513 (ParentRegion == OMPD_parallel ||
4514 ParentRegion == OMPD_target_parallel)) ||
4515 (CancelRegion == OMPD_for &&
4516 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4517 ParentRegion == OMPD_target_parallel_for ||
4518 ParentRegion == OMPD_distribute_parallel_for ||
4519 ParentRegion == OMPD_teams_distribute_parallel_for ||
4520 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4521 (CancelRegion == OMPD_taskgroup &&
4522 (ParentRegion == OMPD_task ||
4523 (SemaRef.getLangOpts().OpenMP >= 50 &&
4524 (ParentRegion == OMPD_taskloop ||
4525 ParentRegion == OMPD_master_taskloop ||
4526 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4527 (CancelRegion == OMPD_sections &&
4528 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4529 ParentRegion == OMPD_parallel_sections)));
4530 OrphanSeen = ParentRegion == OMPD_unknown;
4531 } else if (CurrentRegion == OMPD_master) {
4532 // OpenMP [2.16, Nesting of Regions]
4533 // A master region may not be closely nested inside a worksharing,
4534 // atomic, or explicit task region.
4535 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4536 isOpenMPTaskingDirective(ParentRegion);
4537 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4538 // OpenMP [2.16, Nesting of Regions]
4539 // A critical region may not be nested (closely or otherwise) inside a
4540 // critical region with the same name. Note that this restriction is not
4541 // sufficient to prevent deadlock.
4542 SourceLocation PreviousCriticalLoc;
4543 bool DeadLock = Stack->hasDirective(
4544 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4545 const DeclarationNameInfo &DNI,
4546 SourceLocation Loc) {
4547 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4548 PreviousCriticalLoc = Loc;
4549 return true;
4550 }
4551 return false;
4552 },
4553 false /* skip top directive */);
4554 if (DeadLock) {
4555 SemaRef.Diag(StartLoc,
4556 diag::err_omp_prohibited_region_critical_same_name)
4557 << CurrentName.getName();
4558 if (PreviousCriticalLoc.isValid())
4559 SemaRef.Diag(PreviousCriticalLoc,
4560 diag::note_omp_previous_critical_region);
4561 return true;
4562 }
4563 } else if (CurrentRegion == OMPD_barrier) {
4564 // OpenMP [2.16, Nesting of Regions]
4565 // A barrier region may not be closely nested inside a worksharing,
4566 // explicit task, critical, ordered, atomic, or master region.
4567 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4568 isOpenMPTaskingDirective(ParentRegion) ||
4569 ParentRegion == OMPD_master ||
4570 ParentRegion == OMPD_parallel_master ||
4571 ParentRegion == OMPD_critical ||
4572 ParentRegion == OMPD_ordered;
4573 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4574 !isOpenMPParallelDirective(CurrentRegion) &&
4575 !isOpenMPTeamsDirective(CurrentRegion)) {
4576 // OpenMP [2.16, Nesting of Regions]
4577 // A worksharing region may not be closely nested inside a worksharing,
4578 // explicit task, critical, ordered, atomic, or master region.
4579 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4580 isOpenMPTaskingDirective(ParentRegion) ||
4581 ParentRegion == OMPD_master ||
4582 ParentRegion == OMPD_parallel_master ||
4583 ParentRegion == OMPD_critical ||
4584 ParentRegion == OMPD_ordered;
4585 Recommend = ShouldBeInParallelRegion;
4586 } else if (CurrentRegion == OMPD_ordered) {
4587 // OpenMP [2.16, Nesting of Regions]
4588 // An ordered region may not be closely nested inside a critical,
4589 // atomic, or explicit task region.
4590 // An ordered region must be closely nested inside a loop region (or
4591 // parallel loop region) with an ordered clause.
4592 // OpenMP [2.8.1,simd Construct, Restrictions]
4593 // An ordered construct with the simd clause is the only OpenMP construct
4594 // that can appear in the simd region.
4595 NestingProhibited = ParentRegion == OMPD_critical ||
4596 isOpenMPTaskingDirective(ParentRegion) ||
4597 !(isOpenMPSimdDirective(ParentRegion) ||
4598 Stack->isParentOrderedRegion());
4599 Recommend = ShouldBeInOrderedRegion;
4600 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4601 // OpenMP [2.16, Nesting of Regions]
4602 // If specified, a teams construct must be contained within a target
4603 // construct.
4604 NestingProhibited =
4605 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4606 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4607 ParentRegion != OMPD_target);
4608 OrphanSeen = ParentRegion == OMPD_unknown;
4609 Recommend = ShouldBeInTargetRegion;
4610 } else if (CurrentRegion == OMPD_scan) {
4611 // OpenMP [2.16, Nesting of Regions]
4612 // If specified, a teams construct must be contained within a target
4613 // construct.
4614 NestingProhibited =
4615 SemaRef.LangOpts.OpenMP < 50 ||
4616 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4617 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4618 ParentRegion != OMPD_parallel_for_simd);
4619 OrphanSeen = ParentRegion == OMPD_unknown;
4620 Recommend = ShouldBeInLoopSimdRegion;
4621 }
4622 if (!NestingProhibited &&
4623 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4624 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4625 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4626 // OpenMP [2.16, Nesting of Regions]
4627 // distribute, parallel, parallel sections, parallel workshare, and the
4628 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4629 // constructs that can be closely nested in the teams region.
4630 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4631 !isOpenMPDistributeDirective(CurrentRegion);
4632 Recommend = ShouldBeInParallelRegion;
4633 }
4634 if (!NestingProhibited &&
4635 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4636 // OpenMP 4.5 [2.17 Nesting of Regions]
4637 // The region associated with the distribute construct must be strictly
4638 // nested inside a teams region
4639 NestingProhibited =
4640 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4641 Recommend = ShouldBeInTeamsRegion;
4642 }
4643 if (!NestingProhibited &&
4644 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4645 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4646 // OpenMP 4.5 [2.17 Nesting of Regions]
4647 // If a target, target update, target data, target enter data, or
4648 // target exit data construct is encountered during execution of a
4649 // target region, the behavior is unspecified.
4650 NestingProhibited = Stack->hasDirective(
4651 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4652 SourceLocation) {
4653 if (isOpenMPTargetExecutionDirective(K)) {
4654 OffendingRegion = K;
4655 return true;
4656 }
4657 return false;
4658 },
4659 false /* don't skip top directive */);
4660 CloseNesting = false;
4661 }
4662 if (NestingProhibited) {
4663 if (OrphanSeen) {
4664 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4665 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4666 } else {
4667 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4668 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4669 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4670 }
4671 return true;
4672 }
4673 }
4674 return false;
4675}
4676
4677struct Kind2Unsigned {
4678 using argument_type = OpenMPDirectiveKind;
4679 unsigned operator()(argument_type DK) { return unsigned(DK); }
4680};
4681static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4682 ArrayRef<OMPClause *> Clauses,
4683 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4684 bool ErrorFound = false;
4685 unsigned NamedModifiersNumber = 0;
4686 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4687 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4688 SmallVector<SourceLocation, 4> NameModifierLoc;
4689 for (const OMPClause *C : Clauses) {
4690 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4691 // At most one if clause without a directive-name-modifier can appear on
4692 // the directive.
4693 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4694 if (FoundNameModifiers[CurNM]) {
4695 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4696 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4697 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4698 ErrorFound = true;
4699 } else if (CurNM != OMPD_unknown) {
4700 NameModifierLoc.push_back(IC->getNameModifierLoc());
4701 ++NamedModifiersNumber;
4702 }
4703 FoundNameModifiers[CurNM] = IC;
4704 if (CurNM == OMPD_unknown)
4705 continue;
4706 // Check if the specified name modifier is allowed for the current
4707 // directive.
4708 // At most one if clause with the particular directive-name-modifier can
4709 // appear on the directive.
4710 bool MatchFound = false;
4711 for (auto NM : AllowedNameModifiers) {
4712 if (CurNM == NM) {
4713 MatchFound = true;
4714 break;
4715 }
4716 }
4717 if (!MatchFound) {
4718 S.Diag(IC->getNameModifierLoc(),
4719 diag::err_omp_wrong_if_directive_name_modifier)
4720 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4721 ErrorFound = true;
4722 }
4723 }
4724 }
4725 // If any if clause on the directive includes a directive-name-modifier then
4726 // all if clauses on the directive must include a directive-name-modifier.
4727 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4728 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4729 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4730 diag::err_omp_no_more_if_clause);
4731 } else {
4732 std::string Values;
4733 std::string Sep(", ");
4734 unsigned AllowedCnt = 0;
4735 unsigned TotalAllowedNum =
4736 AllowedNameModifiers.size() - NamedModifiersNumber;
4737 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4738 ++Cnt) {
4739 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4740 if (!FoundNameModifiers[NM]) {
4741 Values += "'";
4742 Values += getOpenMPDirectiveName(NM);
4743 Values += "'";
4744 if (AllowedCnt + 2 == TotalAllowedNum)
4745 Values += " or ";
4746 else if (AllowedCnt + 1 != TotalAllowedNum)
4747 Values += Sep;
4748 ++AllowedCnt;
4749 }
4750 }
4751 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4752 diag::err_omp_unnamed_if_clause)
4753 << (TotalAllowedNum > 1) << Values;
4754 }
4755 for (SourceLocation Loc : NameModifierLoc) {
4756 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4757 }
4758 ErrorFound = true;
4759 }
4760 return ErrorFound;
4761}
4762
4763static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4764 SourceLocation &ELoc,
4765 SourceRange &ERange,
4766 bool AllowArraySection) {
4767 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4768 RefExpr->containsUnexpandedParameterPack())
4769 return std::make_pair(nullptr, true);
4770
4771 // OpenMP [3.1, C/C++]
4772 // A list item is a variable name.
4773 // OpenMP [2.9.3.3, Restrictions, p.1]
4774 // A variable that is part of another variable (as an array or
4775 // structure element) cannot appear in a private clause.
4776 RefExpr = RefExpr->IgnoreParens();
4777 enum {
4778 NoArrayExpr = -1,
4779 ArraySubscript = 0,
4780 OMPArraySection = 1
4781 } IsArrayExpr = NoArrayExpr;
4782 if (AllowArraySection) {
4783 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4784 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4785 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4786 Base = TempASE->getBase()->IgnoreParenImpCasts();
4787 RefExpr = Base;
4788 IsArrayExpr = ArraySubscript;
4789 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4790 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4791 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4792 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4793 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4794 Base = TempASE->getBase()->IgnoreParenImpCasts();
4795 RefExpr = Base;
4796 IsArrayExpr = OMPArraySection;
4797 }
4798 }
4799 ELoc = RefExpr->getExprLoc();
4800 ERange = RefExpr->getSourceRange();
4801 RefExpr = RefExpr->IgnoreParenImpCasts();
4802 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4803 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4804 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4805 (S.getCurrentThisType().isNull() || !ME ||
4806 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4807 !isa<FieldDecl>(ME->getMemberDecl()))) {
4808 if (IsArrayExpr != NoArrayExpr) {
4809 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4810 << ERange;
4811 } else {
4812 S.Diag(ELoc,
4813 AllowArraySection
4814 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4815 : diag::err_omp_expected_var_name_member_expr)
4816 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4817 }
4818 return std::make_pair(nullptr, false);
4819 }
4820 return std::make_pair(
4821 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4822}
4823
4824namespace {
4825/// Checks if the allocator is used in uses_allocators clause to be allowed in
4826/// target regions.
4827class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4828 DSAStackTy *S = nullptr;
4829
4830public:
4831 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4832 return S->isUsesAllocatorsDecl(E->getDecl())
4833 .getValueOr(
4834 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4835 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4836 }
4837 bool VisitStmt(const Stmt *S) {
4838 for (const Stmt *Child : S->children()) {
4839 if (Child && Visit(Child))
4840 return true;
4841 }
4842 return false;
4843 }
4844 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4845};
4846} // namespace
4847
4848static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4849 ArrayRef<OMPClause *> Clauses) {
4850 assert(!S.CurContext->isDependentContext() &&((!S.CurContext->isDependentContext() && "Expected non-dependent context."
) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4851, __PRETTY_FUNCTION__))
4851 "Expected non-dependent context.")((!S.CurContext->isDependentContext() && "Expected non-dependent context."
) ? static_cast<void> (0) : __assert_fail ("!S.CurContext->isDependentContext() && \"Expected non-dependent context.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4851, __PRETTY_FUNCTION__))
;
4852 auto AllocateRange =
4853 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4854 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4855 DeclToCopy;
4856 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4857 return isOpenMPPrivate(C->getClauseKind());
4858 });
4859 for (OMPClause *Cl : PrivateRange) {
4860 MutableArrayRef<Expr *>::iterator I, It, Et;
4861 if (Cl->getClauseKind() == OMPC_private) {
4862 auto *PC = cast<OMPPrivateClause>(Cl);
4863 I = PC->private_copies().begin();
4864 It = PC->varlist_begin();
4865 Et = PC->varlist_end();
4866 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4867 auto *PC = cast<OMPFirstprivateClause>(Cl);
4868 I = PC->private_copies().begin();
4869 It = PC->varlist_begin();
4870 Et = PC->varlist_end();
4871 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4872 auto *PC = cast<OMPLastprivateClause>(Cl);
4873 I = PC->private_copies().begin();
4874 It = PC->varlist_begin();
4875 Et = PC->varlist_end();
4876 } else if (Cl->getClauseKind() == OMPC_linear) {
4877 auto *PC = cast<OMPLinearClause>(Cl);
4878 I = PC->privates().begin();
4879 It = PC->varlist_begin();
4880 Et = PC->varlist_end();
4881 } else if (Cl->getClauseKind() == OMPC_reduction) {
4882 auto *PC = cast<OMPReductionClause>(Cl);
4883 I = PC->privates().begin();
4884 It = PC->varlist_begin();
4885 Et = PC->varlist_end();
4886 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4887 auto *PC = cast<OMPTaskReductionClause>(Cl);
4888 I = PC->privates().begin();
4889 It = PC->varlist_begin();
4890 Et = PC->varlist_end();
4891 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4892 auto *PC = cast<OMPInReductionClause>(Cl);
4893 I = PC->privates().begin();
4894 It = PC->varlist_begin();
4895 Et = PC->varlist_end();
4896 } else {
4897 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4897)
;
4898 }
4899 for (Expr *E : llvm::make_range(It, Et)) {
4900 if (!*I) {
4901 ++I;
4902 continue;
4903 }
4904 SourceLocation ELoc;
4905 SourceRange ERange;
4906 Expr *SimpleRefExpr = E;
4907 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4908 /*AllowArraySection=*/true);
4909 DeclToCopy.try_emplace(Res.first,
4910 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4911 ++I;
4912 }
4913 }
4914 for (OMPClause *C : AllocateRange) {
4915 auto *AC = cast<OMPAllocateClause>(C);
4916 if (S.getLangOpts().OpenMP >= 50 &&
4917 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4918 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4919 AC->getAllocator()) {
4920 Expr *Allocator = AC->getAllocator();
4921 // OpenMP, 2.12.5 target Construct
4922 // Memory allocators that do not appear in a uses_allocators clause cannot
4923 // appear as an allocator in an allocate clause or be used in the target
4924 // region unless a requires directive with the dynamic_allocators clause
4925 // is present in the same compilation unit.
4926 AllocatorChecker Checker(Stack);
4927 if (Checker.Visit(Allocator))
4928 S.Diag(Allocator->getExprLoc(),
4929 diag::err_omp_allocator_not_in_uses_allocators)
4930 << Allocator->getSourceRange();
4931 }
4932 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4933 getAllocatorKind(S, Stack, AC->getAllocator());
4934 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4935 // For task, taskloop or target directives, allocation requests to memory
4936 // allocators with the trait access set to thread result in unspecified
4937 // behavior.
4938 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4939 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4940 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4941 S.Diag(AC->getAllocator()->getExprLoc(),
4942 diag::warn_omp_allocate_thread_on_task_target_directive)
4943 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4944 }
4945 for (Expr *E : AC->varlists()) {
4946 SourceLocation ELoc;
4947 SourceRange ERange;
4948 Expr *SimpleRefExpr = E;
4949 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4950 ValueDecl *VD = Res.first;
4951 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4952 if (!isOpenMPPrivate(Data.CKind)) {
4953 S.Diag(E->getExprLoc(),
4954 diag::err_omp_expected_private_copy_for_allocate);
4955 continue;
4956 }
4957 VarDecl *PrivateVD = DeclToCopy[VD];
4958 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4959 AllocatorKind, AC->getAllocator()))
4960 continue;
4961 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4962 E->getSourceRange());
4963 }
4964 }
4965}
4966
4967StmtResult Sema::ActOnOpenMPExecutableDirective(
4968 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4969 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4970 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4971 StmtResult Res = StmtError();
4972 // First check CancelRegion which is then used in checkNestingOfRegions.
4973 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4974 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
4975 StartLoc))
4976 return StmtError();
4977
4978 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4979 VarsWithInheritedDSAType VarsWithInheritedDSA;
4980 bool ErrorFound = false;
4981 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4982 if (AStmt && !CurContext->isDependentContext()) {
4983 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 4983, __PRETTY_FUNCTION__))
;
4984
4985 // Check default data sharing attributes for referenced variables.
4986 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
4987 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4988 Stmt *S = AStmt;
4989 while (--ThisCaptureLevel >= 0)
4990 S = cast<CapturedStmt>(S)->getCapturedStmt();
4991 DSAChecker.Visit(S);
4992 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4993 !isOpenMPTaskingDirective(Kind)) {
4994 // Visit subcaptures to generate implicit clauses for captured vars.
4995 auto *CS = cast<CapturedStmt>(AStmt);
4996 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4997 getOpenMPCaptureRegions(CaptureRegions, Kind);
4998 // Ignore outer tasking regions for target directives.
4999 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5000 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5001 DSAChecker.visitSubCaptures(CS);
5002 }
5003 if (DSAChecker.isErrorFound())
5004 return StmtError();
5005 // Generate list of implicitly defined firstprivate variables.
5006 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5007
5008 SmallVector<Expr *, 4> ImplicitFirstprivates(
5009 DSAChecker.getImplicitFirstprivate().begin(),
5010 DSAChecker.getImplicitFirstprivate().end());
5011 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5012 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5013 ArrayRef<Expr *> ImplicitMap =
5014 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5015 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5016 }
5017 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5018 for (OMPClause *C : Clauses) {
5019 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5020 for (Expr *E : IRC->taskgroup_descriptors())
5021 if (E)
5022 ImplicitFirstprivates.emplace_back(E);
5023 }
5024 // OpenMP 5.0, 2.10.1 task Construct
5025 // [detach clause]... The event-handle will be considered as if it was
5026 // specified on a firstprivate clause.
5027 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5028 ImplicitFirstprivates.push_back(DC->getEventHandler());
5029 }
5030 if (!ImplicitFirstprivates.empty()) {
5031 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5032 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5033 SourceLocation())) {
5034 ClausesWithImplicit.push_back(Implicit);
5035 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5036 ImplicitFirstprivates.size();
5037 } else {
5038 ErrorFound = true;
5039 }
5040 }
5041 int ClauseKindCnt = -1;
5042 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5043 ++ClauseKindCnt;
5044 if (ImplicitMap.empty())
5045 continue;
5046 CXXScopeSpec MapperIdScopeSpec;
5047 DeclarationNameInfo MapperId;
5048 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5049 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5050 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5051 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5052 ImplicitMap, OMPVarListLocTy())) {
5053 ClausesWithImplicit.emplace_back(Implicit);
5054 ErrorFound |=
5055 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5056 } else {
5057 ErrorFound = true;
5058 }
5059 }
5060 }
5061
5062 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5063 switch (Kind) {
5064 case OMPD_parallel:
5065 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5066 EndLoc);
5067 AllowedNameModifiers.push_back(OMPD_parallel);
5068 break;
5069 case OMPD_simd:
5070 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5071 VarsWithInheritedDSA);
5072 if (LangOpts.OpenMP >= 50)
5073 AllowedNameModifiers.push_back(OMPD_simd);
5074 break;
5075 case OMPD_for:
5076 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5077 VarsWithInheritedDSA);
5078 break;
5079 case OMPD_for_simd:
5080 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5081 EndLoc, VarsWithInheritedDSA);
5082 if (LangOpts.OpenMP >= 50)
5083 AllowedNameModifiers.push_back(OMPD_simd);
5084 break;
5085 case OMPD_sections:
5086 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5087 EndLoc);
5088 break;
5089 case OMPD_section:
5090 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5091, __PRETTY_FUNCTION__))
5091 "No clauses are allowed for 'omp section' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5091, __PRETTY_FUNCTION__))
;
5092 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5093 break;
5094 case OMPD_single:
5095 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5096 EndLoc);
5097 break;
5098 case OMPD_master:
5099 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5100, __PRETTY_FUNCTION__))
5100 "No clauses are allowed for 'omp master' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5100, __PRETTY_FUNCTION__))
;
5101 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5102 break;
5103 case OMPD_critical:
5104 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5105 StartLoc, EndLoc);
5106 break;
5107 case OMPD_parallel_for:
5108 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5109 EndLoc, VarsWithInheritedDSA);
5110 AllowedNameModifiers.push_back(OMPD_parallel);
5111 break;
5112 case OMPD_parallel_for_simd:
5113 Res = ActOnOpenMPParallelForSimdDirective(
5114 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5115 AllowedNameModifiers.push_back(OMPD_parallel);
5116 if (LangOpts.OpenMP >= 50)
5117 AllowedNameModifiers.push_back(OMPD_simd);
5118 break;
5119 case OMPD_parallel_master:
5120 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5121 StartLoc, EndLoc);
5122 AllowedNameModifiers.push_back(OMPD_parallel);
5123 break;
5124 case OMPD_parallel_sections:
5125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5126 StartLoc, EndLoc);
5127 AllowedNameModifiers.push_back(OMPD_parallel);
5128 break;
5129 case OMPD_task:
5130 Res =
5131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5132 AllowedNameModifiers.push_back(OMPD_task);
5133 break;
5134 case OMPD_taskyield:
5135 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5136, __PRETTY_FUNCTION__))
5136 "No clauses are allowed for 'omp taskyield' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5136, __PRETTY_FUNCTION__))
;
5137 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5138, __PRETTY_FUNCTION__))
5138 "No associated statement allowed for 'omp taskyield' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5138, __PRETTY_FUNCTION__))
;
5139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5140 break;
5141 case OMPD_barrier:
5142 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5143, __PRETTY_FUNCTION__))
5143 "No clauses are allowed for 'omp barrier' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5143, __PRETTY_FUNCTION__))
;
5144 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5145, __PRETTY_FUNCTION__))
5145 "No associated statement allowed for 'omp barrier' directive")((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5145, __PRETTY_FUNCTION__))
;
5146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5147 break;
5148 case OMPD_taskwait:
5149 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5150, __PRETTY_FUNCTION__))
5150 "No clauses are allowed for 'omp taskwait' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5150, __PRETTY_FUNCTION__))
;
5151 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5152, __PRETTY_FUNCTION__))
5152 "No associated statement allowed for 'omp taskwait' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5152, __PRETTY_FUNCTION__))
;
5153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5154 break;
5155 case OMPD_taskgroup:
5156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5157 EndLoc);
5158 break;
5159 case OMPD_flush:
5160 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5161, __PRETTY_FUNCTION__))
5161 "No associated statement allowed for 'omp flush' directive")((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5161, __PRETTY_FUNCTION__))
;
5162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5163 break;
5164 case OMPD_depobj:
5165 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5166, __PRETTY_FUNCTION__))
5166 "No associated statement allowed for 'omp depobj' directive")((AStmt == nullptr && "No associated statement allowed for 'omp depobj' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp depobj' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5166, __PRETTY_FUNCTION__))
;
5167 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5168 break;
5169 case OMPD_scan:
5170 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5171, __PRETTY_FUNCTION__))
5171 "No associated statement allowed for 'omp scan' directive")((AStmt == nullptr && "No associated statement allowed for 'omp scan' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp scan' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5171, __PRETTY_FUNCTION__))
;
5172 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5173 break;
5174 case OMPD_ordered:
5175 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5176 EndLoc);
5177 break;
5178 case OMPD_atomic:
5179 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5180 EndLoc);
5181 break;
5182 case OMPD_teams:
5183 Res =
5184 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5185 break;
5186 case OMPD_target:
5187 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5188 EndLoc);
5189 AllowedNameModifiers.push_back(OMPD_target);
5190 break;
5191 case OMPD_target_parallel:
5192 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5193 StartLoc, EndLoc);
5194 AllowedNameModifiers.push_back(OMPD_target);
5195 AllowedNameModifiers.push_back(OMPD_parallel);
5196 break;
5197 case OMPD_target_parallel_for:
5198 Res = ActOnOpenMPTargetParallelForDirective(
5199 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5200 AllowedNameModifiers.push_back(OMPD_target);
5201 AllowedNameModifiers.push_back(OMPD_parallel);
5202 break;
5203 case OMPD_cancellation_point:
5204 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5205, __PRETTY_FUNCTION__))
5205 "No clauses are allowed for 'omp cancellation point' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5205, __PRETTY_FUNCTION__))
;
5206 assert(AStmt == nullptr && "No associated statement allowed for 'omp "((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5207, __PRETTY_FUNCTION__))
5207 "cancellation point' directive")((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5207, __PRETTY_FUNCTION__))
;
5208 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5209 break;
5210 case OMPD_cancel:
5211 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5212, __PRETTY_FUNCTION__))
5212 "No associated statement allowed for 'omp cancel' directive")((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5212, __PRETTY_FUNCTION__))
;
5213 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5214 CancelRegion);
5215 AllowedNameModifiers.push_back(OMPD_cancel);
5216 break;
5217 case OMPD_target_data:
5218 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5219 EndLoc);
5220 AllowedNameModifiers.push_back(OMPD_target_data);
5221 break;
5222 case OMPD_target_enter_data:
5223 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5224 EndLoc, AStmt);
5225 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5226 break;
5227 case OMPD_target_exit_data:
5228 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5229 EndLoc, AStmt);
5230 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5231 break;
5232 case OMPD_taskloop:
5233 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5234 EndLoc, VarsWithInheritedDSA);
5235 AllowedNameModifiers.push_back(OMPD_taskloop);
5236 break;
5237 case OMPD_taskloop_simd:
5238 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5239 EndLoc, VarsWithInheritedDSA);
5240 AllowedNameModifiers.push_back(OMPD_taskloop);
5241 if (LangOpts.OpenMP >= 50)
5242 AllowedNameModifiers.push_back(OMPD_simd);
5243 break;
5244 case OMPD_master_taskloop:
5245 Res = ActOnOpenMPMasterTaskLoopDirective(
5246 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5247 AllowedNameModifiers.push_back(OMPD_taskloop);
5248 break;
5249 case OMPD_master_taskloop_simd:
5250 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5252 AllowedNameModifiers.push_back(OMPD_taskloop);
5253 if (LangOpts.OpenMP >= 50)
5254 AllowedNameModifiers.push_back(OMPD_simd);
5255 break;
5256 case OMPD_parallel_master_taskloop:
5257 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5259 AllowedNameModifiers.push_back(OMPD_taskloop);
5260 AllowedNameModifiers.push_back(OMPD_parallel);
5261 break;
5262 case OMPD_parallel_master_taskloop_simd:
5263 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5264 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5265 AllowedNameModifiers.push_back(OMPD_taskloop);
5266 AllowedNameModifiers.push_back(OMPD_parallel);
5267 if (LangOpts.OpenMP >= 50)
5268 AllowedNameModifiers.push_back(OMPD_simd);
5269 break;
5270 case OMPD_distribute:
5271 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5272 EndLoc, VarsWithInheritedDSA);
5273 break;
5274 case OMPD_target_update:
5275 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5276 EndLoc, AStmt);
5277 AllowedNameModifiers.push_back(OMPD_target_update);
5278 break;
5279 case OMPD_distribute_parallel_for:
5280 Res = ActOnOpenMPDistributeParallelForDirective(
5281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5282 AllowedNameModifiers.push_back(OMPD_parallel);
5283 break;
5284 case OMPD_distribute_parallel_for_simd:
5285 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5286 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5287 AllowedNameModifiers.push_back(OMPD_parallel);
5288 if (LangOpts.OpenMP >= 50)
5289 AllowedNameModifiers.push_back(OMPD_simd);
5290 break;
5291 case OMPD_distribute_simd:
5292 Res = ActOnOpenMPDistributeSimdDirective(
5293 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5294 if (LangOpts.OpenMP >= 50)
5295 AllowedNameModifiers.push_back(OMPD_simd);
5296 break;
5297 case OMPD_target_parallel_for_simd:
5298 Res = ActOnOpenMPTargetParallelForSimdDirective(
5299 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5300 AllowedNameModifiers.push_back(OMPD_target);
5301 AllowedNameModifiers.push_back(OMPD_parallel);
5302 if (LangOpts.OpenMP >= 50)
5303 AllowedNameModifiers.push_back(OMPD_simd);
5304 break;
5305 case OMPD_target_simd:
5306 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5307 EndLoc, VarsWithInheritedDSA);
5308 AllowedNameModifiers.push_back(OMPD_target);
5309 if (LangOpts.OpenMP >= 50)
5310 AllowedNameModifiers.push_back(OMPD_simd);
5311 break;
5312 case OMPD_teams_distribute:
5313 Res = ActOnOpenMPTeamsDistributeDirective(
5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5315 break;
5316 case OMPD_teams_distribute_simd:
5317 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5319 if (LangOpts.OpenMP >= 50)
5320 AllowedNameModifiers.push_back(OMPD_simd);
5321 break;
5322 case OMPD_teams_distribute_parallel_for_simd:
5323 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5325 AllowedNameModifiers.push_back(OMPD_parallel);
5326 if (LangOpts.OpenMP >= 50)
5327 AllowedNameModifiers.push_back(OMPD_simd);
5328 break;
5329 case OMPD_teams_distribute_parallel_for:
5330 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5332 AllowedNameModifiers.push_back(OMPD_parallel);
5333 break;
5334 case OMPD_target_teams:
5335 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5336 EndLoc);
5337 AllowedNameModifiers.push_back(OMPD_target);
5338 break;
5339 case OMPD_target_teams_distribute:
5340 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5341 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5342 AllowedNameModifiers.push_back(OMPD_target);
5343 break;
5344 case OMPD_target_teams_distribute_parallel_for:
5345 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5346 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5347 AllowedNameModifiers.push_back(OMPD_target);
5348 AllowedNameModifiers.push_back(OMPD_parallel);
5349 break;
5350 case OMPD_target_teams_distribute_parallel_for_simd:
5351 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5352 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5353 AllowedNameModifiers.push_back(OMPD_target);
5354 AllowedNameModifiers.push_back(OMPD_parallel);
5355 if (LangOpts.OpenMP >= 50)
5356 AllowedNameModifiers.push_back(OMPD_simd);
5357 break;
5358 case OMPD_target_teams_distribute_simd:
5359 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5361 AllowedNameModifiers.push_back(OMPD_target);
5362 if (LangOpts.OpenMP >= 50)
5363 AllowedNameModifiers.push_back(OMPD_simd);
5364 break;
5365 case OMPD_declare_target:
5366 case OMPD_end_declare_target:
5367 case OMPD_threadprivate:
5368 case OMPD_allocate:
5369 case OMPD_declare_reduction:
5370 case OMPD_declare_mapper:
5371 case OMPD_declare_simd:
5372 case OMPD_requires:
5373 case OMPD_declare_variant:
5374 case OMPD_begin_declare_variant:
5375 case OMPD_end_declare_variant:
5376 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5376)
;
5377 case OMPD_unknown:
5378 default:
5379 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5379)
;
5380 }
5381
5382 ErrorFound = Res.isInvalid() || ErrorFound;
5383
5384 // Check variables in the clauses if default(none) or
5385 // default(firstprivate) was specified.
5386 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5387 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5388 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
5389 for (OMPClause *C : Clauses) {
5390 switch (C->getClauseKind()) {
5391 case OMPC_num_threads:
5392 case OMPC_dist_schedule:
5393 // Do not analyse if no parent teams directive.
5394 if (isOpenMPTeamsDirective(Kind))
5395 break;
5396 continue;
5397 case OMPC_if:
5398 if (isOpenMPTeamsDirective(Kind) &&
5399 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5400 break;
5401 if (isOpenMPParallelDirective(Kind) &&
5402 isOpenMPTaskLoopDirective(Kind) &&
5403 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5404 break;
5405 continue;
5406 case OMPC_schedule:
5407 case OMPC_detach:
5408 break;
5409 case OMPC_grainsize:
5410 case OMPC_num_tasks:
5411 case OMPC_final:
5412 case OMPC_priority:
5413 // Do not analyze if no parent parallel directive.
5414 if (isOpenMPParallelDirective(Kind))
5415 break;
5416 continue;
5417 case OMPC_ordered:
5418 case OMPC_device:
5419 case OMPC_num_teams:
5420 case OMPC_thread_limit:
5421 case OMPC_hint:
5422 case OMPC_collapse:
5423 case OMPC_safelen:
5424 case OMPC_simdlen:
5425 case OMPC_default:
5426 case OMPC_proc_bind:
5427 case OMPC_private:
5428 case OMPC_firstprivate:
5429 case OMPC_lastprivate:
5430 case OMPC_shared:
5431 case OMPC_reduction:
5432 case OMPC_task_reduction:
5433 case OMPC_in_reduction:
5434 case OMPC_linear:
5435 case OMPC_aligned:
5436 case OMPC_copyin:
5437 case OMPC_copyprivate:
5438 case OMPC_nowait:
5439 case OMPC_untied:
5440 case OMPC_mergeable:
5441 case OMPC_allocate:
5442 case OMPC_read:
5443 case OMPC_write:
5444 case OMPC_update:
5445 case OMPC_capture:
5446 case OMPC_seq_cst:
5447 case OMPC_acq_rel:
5448 case OMPC_acquire:
5449 case OMPC_release:
5450 case OMPC_relaxed:
5451 case OMPC_depend:
5452 case OMPC_threads:
5453 case OMPC_simd:
5454 case OMPC_map:
5455 case OMPC_nogroup:
5456 case OMPC_defaultmap:
5457 case OMPC_to:
5458 case OMPC_from:
5459 case OMPC_use_device_ptr:
5460 case OMPC_use_device_addr:
5461 case OMPC_is_device_ptr:
5462 case OMPC_nontemporal:
5463 case OMPC_order:
5464 case OMPC_destroy:
5465 case OMPC_inclusive:
5466 case OMPC_exclusive:
5467 case OMPC_uses_allocators:
5468 case OMPC_affinity:
5469 continue;
5470 case OMPC_allocator:
5471 case OMPC_flush:
5472 case OMPC_depobj:
5473 case OMPC_threadprivate:
5474 case OMPC_uniform:
5475 case OMPC_unknown:
5476 case OMPC_unified_address:
5477 case OMPC_unified_shared_memory:
5478 case OMPC_reverse_offload:
5479 case OMPC_dynamic_allocators:
5480 case OMPC_atomic_default_mem_order:
5481 case OMPC_device_type:
5482 case OMPC_match:
5483 default:
5484 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5484)
;
5485 }
5486 for (Stmt *CC : C->children()) {
5487 if (CC)
5488 DSAChecker.Visit(CC);
5489 }
5490 }
5491 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5492 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5493 }
5494 for (const auto &P : VarsWithInheritedDSA) {
5495 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5496 continue;
5497 ErrorFound = true;
5498 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none ||
5499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_firstprivate) {
5500 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5501 << P.first << P.second->getSourceRange();
5502 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5503 } else if (getLangOpts().OpenMP >= 50) {
5504 Diag(P.second->getExprLoc(),
5505 diag::err_omp_defaultmap_no_attr_for_variable)
5506 << P.first << P.second->getSourceRange();
5507 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5508 diag::note_omp_defaultmap_attr_none);
5509 }
5510 }
5511
5512 if (!AllowedNameModifiers.empty())
5513 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5514 ErrorFound;
5515
5516 if (ErrorFound)
5517 return StmtError();
5518
5519 if (!CurContext->isDependentContext() &&
5520 isOpenMPTargetExecutionDirective(Kind) &&
5521 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5522 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5523 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5524 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5525 // Register target to DSA Stack.
5526 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5527 }
5528
5529 return Res;
5530}
5531
5532Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5533 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5534 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5535 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5536 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5537 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5537, __PRETTY_FUNCTION__))
;
5538 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5538, __PRETTY_FUNCTION__))
;
5539 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5539, __PRETTY_FUNCTION__))
;
5540 if (!DG || DG.get().isNull())
5541 return DeclGroupPtrTy();
5542
5543 const int SimdId = 0;
5544 if (!DG.get().isSingleDecl()) {
5545 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5546 << SimdId;
5547 return DG;
5548 }
5549 Decl *ADecl = DG.get().getSingleDecl();
5550 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5551 ADecl = FTD->getTemplatedDecl();
5552
5553 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5554 if (!FD) {
5555 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5556 return DeclGroupPtrTy();
5557 }
5558
5559 // OpenMP [2.8.2, declare simd construct, Description]
5560 // The parameter of the simdlen clause must be a constant positive integer
5561 // expression.
5562 ExprResult SL;
5563 if (Simdlen)
5564 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5565 // OpenMP [2.8.2, declare simd construct, Description]
5566 // The special this pointer can be used as if was one of the arguments to the
5567 // function in any of the linear, aligned, or uniform clauses.
5568 // The uniform clause declares one or more arguments to have an invariant
5569 // value for all concurrent invocations of the function in the execution of a
5570 // single SIMD loop.
5571 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5572 const Expr *UniformedLinearThis = nullptr;
5573 for (const Expr *E : Uniforms) {
5574 E = E->IgnoreParenImpCasts();
5575 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5576 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5577 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5578 FD->getParamDecl(PVD->getFunctionScopeIndex())
5579 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5580 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5581 continue;
5582 }
5583 if (isa<CXXThisExpr>(E)) {
5584 UniformedLinearThis = E;
5585 continue;
5586 }
5587 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5588 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5589 }
5590 // OpenMP [2.8.2, declare simd construct, Description]
5591 // The aligned clause declares that the object to which each list item points
5592 // is aligned to the number of bytes expressed in the optional parameter of
5593 // the aligned clause.
5594 // The special this pointer can be used as if was one of the arguments to the
5595 // function in any of the linear, aligned, or uniform clauses.
5596 // The type of list items appearing in the aligned clause must be array,
5597 // pointer, reference to array, or reference to pointer.
5598 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5599 const Expr *AlignedThis = nullptr;
5600 for (const Expr *E : Aligneds) {
5601 E = E->IgnoreParenImpCasts();
5602 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5603 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5604 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5605 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5606 FD->getParamDecl(PVD->getFunctionScopeIndex())
5607 ->getCanonicalDecl() == CanonPVD) {
5608 // OpenMP [2.8.1, simd construct, Restrictions]
5609 // A list-item cannot appear in more than one aligned clause.
5610 if (AlignedArgs.count(CanonPVD) > 0) {
5611 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5612 << 1 << getOpenMPClauseName(OMPC_aligned)
5613 << E->getSourceRange();
5614 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5615 diag::note_omp_explicit_dsa)
5616 << getOpenMPClauseName(OMPC_aligned);
5617 continue;
5618 }
5619 AlignedArgs[CanonPVD] = E;
5620 QualType QTy = PVD->getType()
5621 .getNonReferenceType()
5622 .getUnqualifiedType()
5623 .getCanonicalType();
5624 const Type *Ty = QTy.getTypePtrOrNull();
5625 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5626 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5627 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5628 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5629 }
5630 continue;
5631 }
5632 }
5633 if (isa<CXXThisExpr>(E)) {
5634 if (AlignedThis) {
5635 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5636 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5637 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5638 << getOpenMPClauseName(OMPC_aligned);
5639 }
5640 AlignedThis = E;
5641 continue;
5642 }
5643 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5644 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5645 }
5646 // The optional parameter of the aligned clause, alignment, must be a constant
5647 // positive integer expression. If no optional parameter is specified,
5648 // implementation-defined default alignments for SIMD instructions on the
5649 // target platforms are assumed.
5650 SmallVector<const Expr *, 4> NewAligns;
5651 for (Expr *E : Alignments) {
5652 ExprResult Align;
5653 if (E)
5654 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5655 NewAligns.push_back(Align.get());
5656 }
5657 // OpenMP [2.8.2, declare simd construct, Description]
5658 // The linear clause declares one or more list items to be private to a SIMD
5659 // lane and to have a linear relationship with respect to the iteration space
5660 // of a loop.
5661 // The special this pointer can be used as if was one of the arguments to the
5662 // function in any of the linear, aligned, or uniform clauses.
5663 // When a linear-step expression is specified in a linear clause it must be
5664 // either a constant integer expression or an integer-typed parameter that is
5665 // specified in a uniform clause on the directive.
5666 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5667 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5668 auto MI = LinModifiers.begin();
5669 for (const Expr *E : Linears) {
5670 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5671 ++MI;
5672 E = E->IgnoreParenImpCasts();
5673 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5674 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5675 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5676 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5677 FD->getParamDecl(PVD->getFunctionScopeIndex())
5678 ->getCanonicalDecl() == CanonPVD) {
5679 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5680 // A list-item cannot appear in more than one linear clause.
5681 if (LinearArgs.count(CanonPVD) > 0) {
5682 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5683 << getOpenMPClauseName(OMPC_linear)
5684 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5685 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5686 diag::note_omp_explicit_dsa)
5687 << getOpenMPClauseName(OMPC_linear);
5688 continue;
5689 }
5690 // Each argument can appear in at most one uniform or linear clause.
5691 if (UniformedArgs.count(CanonPVD) > 0) {
5692 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5693 << getOpenMPClauseName(OMPC_linear)
5694 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5695 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5696 diag::note_omp_explicit_dsa)
5697 << getOpenMPClauseName(OMPC_uniform);
5698 continue;
5699 }
5700 LinearArgs[CanonPVD] = E;
5701 if (E->isValueDependent() || E->isTypeDependent() ||
5702 E->isInstantiationDependent() ||
5703 E->containsUnexpandedParameterPack())
5704 continue;
5705 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5706 PVD->getOriginalType(),
5707 /*IsDeclareSimd=*/true);
5708 continue;
5709 }
5710 }
5711 if (isa<CXXThisExpr>(E)) {
5712 if (UniformedLinearThis) {
5713 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5714 << getOpenMPClauseName(OMPC_linear)
5715 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5716 << E->getSourceRange();
5717 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5718 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5719 : OMPC_linear);
5720 continue;
5721 }
5722 UniformedLinearThis = E;
5723 if (E->isValueDependent() || E->isTypeDependent() ||
5724 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5725 continue;
5726 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5727 E->getType(), /*IsDeclareSimd=*/true);
5728 continue;
5729 }
5730 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5731 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5732 }
5733 Expr *Step = nullptr;
5734 Expr *NewStep = nullptr;
5735 SmallVector<Expr *, 4> NewSteps;
5736 for (Expr *E : Steps) {
5737 // Skip the same step expression, it was checked already.
5738 if (Step == E || !E) {
5739 NewSteps.push_back(E ? NewStep : nullptr);
5740 continue;
5741 }
5742 Step = E;
5743 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5744 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5745 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5746 if (UniformedArgs.count(CanonPVD) == 0) {
5747 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5748 << Step->getSourceRange();
5749 } else if (E->isValueDependent() || E->isTypeDependent() ||
5750 E->isInstantiationDependent() ||
5751 E->containsUnexpandedParameterPack() ||
5752 CanonPVD->getType()->hasIntegerRepresentation()) {
5753 NewSteps.push_back(Step);
5754 } else {
5755 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5756 << Step->getSourceRange();
5757 }
5758 continue;
5759 }
5760 NewStep = Step;
5761 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5762 !Step->isInstantiationDependent() &&
5763 !Step->containsUnexpandedParameterPack()) {
5764 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5765 .get();
5766 if (NewStep)
5767 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5768 }
5769 NewSteps.push_back(NewStep);
5770 }
5771 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5772 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5773 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5774 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5775 const_cast<Expr **>(Linears.data()), Linears.size(),
5776 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5777 NewSteps.data(), NewSteps.size(), SR);
5778 ADecl->addAttr(NewAttr);
5779 return DG;
5780}
5781
5782static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5783 QualType NewType) {
5784 assert(NewType->isFunctionProtoType() &&((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5785, __PRETTY_FUNCTION__))
5785 "Expected function type with prototype.")((NewType->isFunctionProtoType() && "Expected function type with prototype."
) ? static_cast<void> (0) : __assert_fail ("NewType->isFunctionProtoType() && \"Expected function type with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5785, __PRETTY_FUNCTION__))
;
5786 assert(FD->getType()->isFunctionNoProtoType() &&((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5787, __PRETTY_FUNCTION__))
5787 "Expected function with type with no prototype.")((FD->getType()->isFunctionNoProtoType() && "Expected function with type with no prototype."
) ? static_cast<void> (0) : __assert_fail ("FD->getType()->isFunctionNoProtoType() && \"Expected function with type with no prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5787, __PRETTY_FUNCTION__))
;
5788 assert(FDWithProto->getType()->isFunctionProtoType() &&((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5789, __PRETTY_FUNCTION__))
5789 "Expected function with prototype.")((FDWithProto->getType()->isFunctionProtoType() &&
"Expected function with prototype.") ? static_cast<void>
(0) : __assert_fail ("FDWithProto->getType()->isFunctionProtoType() && \"Expected function with prototype.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 5789, __PRETTY_FUNCTION__))
;
5790 // Synthesize parameters with the same types.
5791 FD->setType(NewType);
5792 SmallVector<ParmVarDecl *, 16> Params;
5793 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5794 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5795 SourceLocation(), nullptr, P->getType(),
5796 /*TInfo=*/nullptr, SC_None, nullptr);
5797 Param->setScopeInfo(0, Params.size());
5798 Param->setImplicit();
5799 Params.push_back(Param);
5800 }
5801
5802 FD->setParams(Params);
5803}
5804
5805Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5806 : TI(&TI), NameSuffix(TI.getMangledName()) {}
5807
5808FunctionDecl *
5809Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
5810 Declarator &D) {
5811 IdentifierInfo *BaseII = D.getIdentifier();
5812 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5813 LookupOrdinaryName);
5814 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5815
5816 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5817 QualType FType = TInfo->getType();
5818
5819 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr;
5820 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval;
5821
5822 FunctionDecl *BaseFD = nullptr;
5823 for (auto *Candidate : Lookup) {
5824 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl());
5825 if (!UDecl)
5826 continue;
5827
5828 // Don't specialize constexpr/consteval functions with
5829 // non-constexpr/consteval functions.
5830 if (UDecl->isConstexpr() && !IsConstexpr)
5831 continue;
5832 if (UDecl->isConsteval() && !IsConsteval)
5833 continue;
5834
5835 QualType NewType = Context.mergeFunctionTypes(
5836 FType, UDecl->getType(), /* OfBlockPointer */ false,
5837 /* Unqualified */ false, /* AllowCXX */ true);
5838 if (NewType.isNull())
5839 continue;
5840
5841 // Found a base!
5842 BaseFD = UDecl;
5843 break;
5844 }
5845 if (!BaseFD) {
5846 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D));
5847 BaseFD->setImplicit(true);
5848 }
5849
5850 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5851 std::string MangledName;
5852 MangledName += D.getIdentifier()->getName();
5853 MangledName += getOpenMPVariantManglingSeparatorStr();
5854 MangledName += DVScope.NameSuffix;
5855 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5856
5857 VariantII.setMangledOpenMPVariantName(true);
5858 D.SetIdentifier(&VariantII, D.getBeginLoc());
5859 return BaseFD;
5860}
5861
5862void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5863 FunctionDecl *FD, FunctionDecl *BaseFD) {
5864 // Do not mark function as is used to prevent its emission if this is the
5865 // only place where it is used.
5866 EnterExpressionEvaluationContext Unevaluated(
5867 *this, Sema::ExpressionEvaluationContext::Unevaluated);
5868
5869 Expr *VariantFuncRef = DeclRefExpr::Create(
5870 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5871 /* RefersToEnclosingVariableOrCapture */ false,
5872 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5873
5874 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5875 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5876 Context, VariantFuncRef, DVScope.TI);
5877 BaseFD->addAttr(OMPDeclareVariantA);
5878}
5879
5880ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5881 SourceLocation LParenLoc,
5882 MultiExprArg ArgExprs,
5883 SourceLocation RParenLoc, Expr *ExecConfig) {
5884 // The common case is a regular call we do not want to specialize at all. Try
5885 // to make that case fast by bailing early.
5886 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
5887 if (!CE)
5888 return Call;
5889
5890 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
5891 if (!CalleeFnDecl)
5892 return Call;
5893
5894 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
5895 return Call;
5896
5897 ASTContext &Context = getASTContext();
5898 std::function<void(StringRef)> DiagUnknownTrait = [this,
5899 CE](StringRef ISATrait) {
5900 // TODO Track the selector locations in a way that is accessible here to
5901 // improve the diagnostic location.
5902 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
5903 << ISATrait;
5904 };
5905 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
5906 getCurFunctionDecl());
5907
5908 SmallVector<Expr *, 4> Exprs;
5909 SmallVector<VariantMatchInfo, 4> VMIs;
5910 while (CalleeFnDecl) {
5911 for (OMPDeclareVariantAttr *A :
5912 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
5913 Expr *VariantRef = A->getVariantFuncRef();
5914
5915 VariantMatchInfo VMI;
5916 OMPTraitInfo &TI = A->getTraitInfo();
5917 TI.getAsVariantMatchInfo(Context, VMI);
5918 if (!isVariantApplicableInContext(VMI, OMPCtx,
5919 /* DeviceSetOnly */ false))
5920 continue;
5921
5922 VMIs.push_back(VMI);
5923 Exprs.push_back(VariantRef);
5924 }
5925
5926 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
5927 }
5928
5929 ExprResult NewCall;
5930 do {
5931 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
5932 if (BestIdx < 0)
5933 return Call;
5934 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
5935 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
5936
5937 {
5938 // Try to build a (member) call expression for the current best applicable
5939 // variant expression. We allow this to fail in which case we continue
5940 // with the next best variant expression. The fail case is part of the
5941 // implementation defined behavior in the OpenMP standard when it talks
5942 // about what differences in the function prototypes: "Any differences
5943 // that the specific OpenMP context requires in the prototype of the
5944 // variant from the base function prototype are implementation defined."
5945 // This wording is there to allow the specialized variant to have a
5946 // different type than the base function. This is intended and OK but if
5947 // we cannot create a call the difference is not in the "implementation
5948 // defined range" we allow.
5949 Sema::TentativeAnalysisScope Trap(*this);
5950
5951 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
5952 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
5953 BestExpr = MemberExpr::CreateImplicit(
5954 Context, MemberCall->getImplicitObjectArgument(),
5955 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
5956 MemberCall->getValueKind(), MemberCall->getObjectKind());
5957 }
5958 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
5959 ExecConfig);
5960 if (NewCall.isUsable())
5961 break;
5962 }
5963
5964 VMIs.erase(VMIs.begin() + BestIdx);
5965 Exprs.erase(Exprs.begin() + BestIdx);
5966 } while (!VMIs.empty());
5967
5968 if (!NewCall.isUsable())
5969 return Call;
5970 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
5971}
5972
5973Optional<std::pair<FunctionDecl *, Expr *>>
5974Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
5975 Expr *VariantRef, OMPTraitInfo &TI,
5976 SourceRange SR) {
5977 if (!DG || DG.get().isNull())
5978 return None;
5979
5980 const int VariantId = 1;
5981 // Must be applied only to single decl.
5982 if (!DG.get().isSingleDecl()) {
5983 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5984 << VariantId << SR;
5985 return None;
5986 }
5987 Decl *ADecl = DG.get().getSingleDecl();
5988 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5989 ADecl = FTD->getTemplatedDecl();
5990
5991 // Decl must be a function.
5992 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5993 if (!FD) {
5994 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5995 << VariantId << SR;
5996 return None;
5997 }
5998
5999 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6000 return FD->hasAttrs() &&
6001 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6002 FD->hasAttr<TargetAttr>());
6003 };
6004 // OpenMP is not compatible with CPU-specific attributes.
6005 if (HasMultiVersionAttributes(FD)) {
6006 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6007 << SR;
6008 return None;
6009 }
6010
6011 // Allow #pragma omp declare variant only if the function is not used.
6012 if (FD->isUsed(false))
6013 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6014 << FD->getLocation();
6015
6016 // Check if the function was emitted already.
6017 const FunctionDecl *Definition;
6018 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6019 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6020 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6021 << FD->getLocation();
6022
6023 // The VariantRef must point to function.
6024 if (!VariantRef) {
6025 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6026 return None;
6027 }
6028
6029 auto ShouldDelayChecks = [](Expr *&E, bool) {
6030 return E && (E->isTypeDependent() || E->isValueDependent() ||
6031 E->containsUnexpandedParameterPack() ||
6032 E->isInstantiationDependent());
6033 };
6034 // Do not check templates, wait until instantiation.
6035 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6036 TI.anyScoreOrCondition(ShouldDelayChecks))
6037 return std::make_pair(FD, VariantRef);
6038
6039 // Deal with non-constant score and user condition expressions.
6040 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6041 bool IsScore) -> bool {
6042 if (!E || E->isIntegerConstantExpr(Context))
6043 return false;
6044
6045 if (IsScore) {
6046 // We warn on non-constant scores and pretend they were not present.
6047 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6048 << E;
6049 E = nullptr;
6050 } else {
6051 // We could replace a non-constant user condition with "false" but we
6052 // will soon need to handle these anyway for the dynamic version of
6053 // OpenMP context selectors.
6054 Diag(E->getExprLoc(),
6055 diag::err_omp_declare_variant_user_condition_not_constant)
6056 << E;
6057 }
6058 return true;
6059 };
6060 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6061 return None;
6062
6063 // Convert VariantRef expression to the type of the original function to
6064 // resolve possible conflicts.
6065 ExprResult VariantRefCast;
6066 if (LangOpts.CPlusPlus) {
6067 QualType FnPtrType;
6068 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6069 if (Method && !Method->isStatic()) {
6070 const Type *ClassType =
6071 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6072 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6073 ExprResult ER;
6074 {
6075 // Build adrr_of unary op to correctly handle type checks for member
6076 // functions.
6077 Sema::TentativeAnalysisScope Trap(*this);
6078 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6079 VariantRef);
6080 }
6081 if (!ER.isUsable()) {
6082 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6083 << VariantId << VariantRef->getSourceRange();
6084 return None;
6085 }
6086 VariantRef = ER.get();
6087 } else {
6088 FnPtrType = Context.getPointerType(FD->getType());
6089 }
6090 ImplicitConversionSequence ICS =
6091 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
6092 /*SuppressUserConversions=*/false,
6093 AllowedExplicit::None,
6094 /*InOverloadResolution=*/false,
6095 /*CStyle=*/false,
6096 /*AllowObjCWritebackConversion=*/false);
6097 if (ICS.isFailure()) {
6098 Diag(VariantRef->getExprLoc(),
6099 diag::err_omp_declare_variant_incompat_types)
6100 << VariantRef->getType()
6101 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6102 << VariantRef->getSourceRange();
6103 return None;
6104 }
6105 VariantRefCast = PerformImplicitConversion(
6106 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6107 if (!VariantRefCast.isUsable())
6108 return None;
6109 // Drop previously built artificial addr_of unary op for member functions.
6110 if (Method && !Method->isStatic()) {
6111 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6112 if (auto *UO = dyn_cast<UnaryOperator>(
6113 PossibleAddrOfVariantRef->IgnoreImplicit()))
6114 VariantRefCast = UO->getSubExpr();
6115 }
6116 } else {
6117 VariantRefCast = VariantRef;
6118 }
6119
6120 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6121 if (!ER.isUsable() ||
6122 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6123 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6124 << VariantId << VariantRef->getSourceRange();
6125 return None;
6126 }
6127
6128 // The VariantRef must point to function.
6129 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6130 if (!DRE) {
6131 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6132 << VariantId << VariantRef->getSourceRange();
6133 return None;
6134 }
6135 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6136 if (!NewFD) {
6137 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6138 << VariantId << VariantRef->getSourceRange();
6139 return None;
6140 }
6141
6142 // Check if function types are compatible in C.
6143 if (!LangOpts.CPlusPlus) {
6144 QualType NewType =
6145 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6146 if (NewType.isNull()) {
6147 Diag(VariantRef->getExprLoc(),
6148 diag::err_omp_declare_variant_incompat_types)
6149 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6150 return None;
6151 }
6152 if (NewType->isFunctionProtoType()) {
6153 if (FD->getType()->isFunctionNoProtoType())
6154 setPrototype(*this, FD, NewFD, NewType);
6155 else if (NewFD->getType()->isFunctionNoProtoType())
6156 setPrototype(*this, NewFD, FD, NewType);
6157 }
6158 }
6159
6160 // Check if variant function is not marked with declare variant directive.
6161 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6162 Diag(VariantRef->getExprLoc(),
6163 diag::warn_omp_declare_variant_marked_as_declare_variant)
6164 << VariantRef->getSourceRange();
6165 SourceRange SR =
6166 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6167 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6168 return None;
6169 }
6170
6171 enum DoesntSupport {
6172 VirtFuncs = 1,
6173 Constructors = 3,
6174 Destructors = 4,
6175 DeletedFuncs = 5,
6176 DefaultedFuncs = 6,
6177 ConstexprFuncs = 7,
6178 ConstevalFuncs = 8,
6179 };
6180 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6181 if (CXXFD->isVirtual()) {
6182 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6183 << VirtFuncs;
6184 return None;
6185 }
6186
6187 if (isa<CXXConstructorDecl>(FD)) {
6188 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6189 << Constructors;
6190 return None;
6191 }
6192
6193 if (isa<CXXDestructorDecl>(FD)) {
6194 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6195 << Destructors;
6196 return None;
6197 }
6198 }
6199
6200 if (FD->isDeleted()) {
6201 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6202 << DeletedFuncs;
6203 return None;
6204 }
6205
6206 if (FD->isDefaulted()) {
6207 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6208 << DefaultedFuncs;
6209 return None;
6210 }
6211
6212 if (FD->isConstexpr()) {
6213 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6214 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6215 return None;
6216 }
6217
6218 // Check general compatibility.
6219 if (areMultiversionVariantFunctionsCompatible(
6220 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6221 PartialDiagnosticAt(SourceLocation(),
6222 PartialDiagnostic::NullDiagnostic()),
6223 PartialDiagnosticAt(
6224 VariantRef->getExprLoc(),
6225 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6226 PartialDiagnosticAt(VariantRef->getExprLoc(),
6227 PDiag(diag::err_omp_declare_variant_diff)
6228 << FD->getLocation()),
6229 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6230 /*CLinkageMayDiffer=*/true))
6231 return None;
6232 return std::make_pair(FD, cast<Expr>(DRE));
6233}
6234
6235void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6236 Expr *VariantRef,
6237 OMPTraitInfo &TI,
6238 SourceRange SR) {
6239 auto *NewAttr =
6240 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6241 FD->addAttr(NewAttr);
6242}
6243
6244StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6245 Stmt *AStmt,
6246 SourceLocation StartLoc,
6247 SourceLocation EndLoc) {
6248 if (!AStmt)
6249 return StmtError();
6250
6251 auto *CS = cast<CapturedStmt>(AStmt);
6252 // 1.2.2 OpenMP Language Terminology
6253 // Structured block - An executable statement with a single entry at the
6254 // top and a single exit at the bottom.
6255 // The point of exit cannot be a branch out of the structured block.
6256 // longjmp() and throw() must not violate the entry/exit criteria.
6257 CS->getCapturedDecl()->setNothrow();
6258
6259 setFunctionHasBranchProtectedScope();
6260
6261 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6262 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
6263 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6264}
6265
6266namespace {
6267/// Iteration space of a single for loop.
6268struct LoopIterationSpace final {
6269 /// True if the condition operator is the strict compare operator (<, > or
6270 /// !=).
6271 bool IsStrictCompare = false;
6272 /// Condition of the loop.
6273 Expr *PreCond = nullptr;
6274 /// This expression calculates the number of iterations in the loop.
6275 /// It is always possible to calculate it before starting the loop.
6276 Expr *NumIterations = nullptr;
6277 /// The loop counter variable.
6278 Expr *CounterVar = nullptr;
6279 /// Private loop counter variable.
6280 Expr *PrivateCounterVar = nullptr;
6281 /// This is initializer for the initial value of #CounterVar.
6282 Expr *CounterInit = nullptr;
6283 /// This is step for the #CounterVar used to generate its update:
6284 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6285 Expr *CounterStep = nullptr;
6286 /// Should step be subtracted?
6287 bool Subtract = false;
6288 /// Source range of the loop init.
6289 SourceRange InitSrcRange;
6290 /// Source range of the loop condition.
6291 SourceRange CondSrcRange;
6292 /// Source range of the loop increment.
6293 SourceRange IncSrcRange;
6294 /// Minimum value that can have the loop control variable. Used to support
6295 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6296 /// since only such variables can be used in non-loop invariant expressions.
6297 Expr *MinValue = nullptr;
6298 /// Maximum value that can have the loop control variable. Used to support
6299 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6300 /// since only such variables can be used in non-loop invariant expressions.
6301 Expr *MaxValue = nullptr;
6302 /// true, if the lower bound depends on the outer loop control var.
6303 bool IsNonRectangularLB = false;
6304 /// true, if the upper bound depends on the outer loop control var.
6305 bool IsNonRectangularUB = false;
6306 /// Index of the loop this loop depends on and forms non-rectangular loop
6307 /// nest.
6308 unsigned LoopDependentIdx = 0;
6309 /// Final condition for the non-rectangular loop nest support. It is used to
6310 /// check that the number of iterations for this particular counter must be
6311 /// finished.
6312 Expr *FinalCondition = nullptr;
6313};
6314
6315/// Helper class for checking canonical form of the OpenMP loops and
6316/// extracting iteration space of each loop in the loop nest, that will be used
6317/// for IR generation.
6318class OpenMPIterationSpaceChecker {
6319 /// Reference to Sema.
6320 Sema &SemaRef;
6321 /// Data-sharing stack.
6322 DSAStackTy &Stack;
6323 /// A location for diagnostics (when there is no some better location).
6324 SourceLocation DefaultLoc;
6325 /// A location for diagnostics (when increment is not compatible).
6326 SourceLocation ConditionLoc;
6327 /// A source location for referring to loop init later.
6328 SourceRange InitSrcRange;
6329 /// A source location for referring to condition later.
6330 SourceRange ConditionSrcRange;
6331 /// A source location for referring to increment later.
6332 SourceRange IncrementSrcRange;
6333 /// Loop variable.
6334 ValueDecl *LCDecl = nullptr;
6335 /// Reference to loop variable.
6336 Expr *LCRef = nullptr;
6337 /// Lower bound (initializer for the var).
6338 Expr *LB = nullptr;
6339 /// Upper bound.
6340 Expr *UB = nullptr;
6341 /// Loop step (increment).
6342 Expr *Step = nullptr;
6343 /// This flag is true when condition is one of:
6344 /// Var < UB
6345 /// Var <= UB
6346 /// UB > Var
6347 /// UB >= Var
6348 /// This will have no value when the condition is !=
6349 llvm::Optional<bool> TestIsLessOp;
6350 /// This flag is true when condition is strict ( < or > ).
6351 bool TestIsStrictOp = false;
6352 /// This flag is true when step is subtracted on each iteration.
6353 bool SubtractStep = false;
6354 /// The outer loop counter this loop depends on (if any).
6355 const ValueDecl *DepDecl = nullptr;
6356 /// Contains number of loop (starts from 1) on which loop counter init
6357 /// expression of this loop depends on.
6358 Optional<unsigned> InitDependOnLC;
6359 /// Contains number of loop (starts from 1) on which loop counter condition
6360 /// expression of this loop depends on.
6361 Optional<unsigned> CondDependOnLC;
6362 /// Checks if the provide statement depends on the loop counter.
6363 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6364 /// Original condition required for checking of the exit condition for
6365 /// non-rectangular loop.
6366 Expr *Condition = nullptr;
6367
6368public:
6369 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6370 SourceLocation DefaultLoc)
6371 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6372 ConditionLoc(DefaultLoc) {}
6373 /// Check init-expr for canonical loop form and save loop counter
6374 /// variable - #Var and its initialization value - #LB.
6375 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6376 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6377 /// for less/greater and for strict/non-strict comparison.
6378 bool checkAndSetCond(Expr *S);
6379 /// Check incr-expr for canonical loop form and return true if it
6380 /// does not conform, otherwise save loop step (#Step).
6381 bool checkAndSetInc(Expr *S);
6382 /// Return the loop counter variable.
6383 ValueDecl *getLoopDecl() const { return LCDecl; }
6384 /// Return the reference expression to loop counter variable.
6385 Expr *getLoopDeclRefExpr() const { return LCRef; }
6386 /// Source range of the loop init.
6387 SourceRange getInitSrcRange() const { return InitSrcRange; }
6388 /// Source range of the loop condition.
6389 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6390 /// Source range of the loop increment.
6391 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6392 /// True if the step should be subtracted.
6393 bool shouldSubtractStep() const { return SubtractStep; }
6394 /// True, if the compare operator is strict (<, > or !=).
6395 bool isStrictTestOp() const { return TestIsStrictOp; }
6396 /// Build the expression to calculate the number of iterations.
6397 Expr *buildNumIterations(
6398 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6399 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6400 /// Build the precondition expression for the loops.
6401 Expr *
6402 buildPreCond(Scope *S, Expr *Cond,
6403 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6404 /// Build reference expression to the counter be used for codegen.
6405 DeclRefExpr *
6406 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6407 DSAStackTy &DSA) const;
6408 /// Build reference expression to the private counter be used for
6409 /// codegen.
6410 Expr *buildPrivateCounterVar() const;
6411 /// Build initialization of the counter be used for codegen.
6412 Expr *buildCounterInit() const;
6413 /// Build step of the counter be used for codegen.
6414 Expr *buildCounterStep() const;
6415 /// Build loop data with counter value for depend clauses in ordered
6416 /// directives.
6417 Expr *
6418 buildOrderedLoopData(Scope *S, Expr *Counter,
6419 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6420 SourceLocation Loc, Expr *Inc = nullptr,
6421 OverloadedOperatorKind OOK = OO_Amp);
6422 /// Builds the minimum value for the loop counter.
6423 std::pair<Expr *, Expr *> buildMinMaxValues(
6424 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6425 /// Builds final condition for the non-rectangular loops.
6426 Expr *buildFinalCondition(Scope *S) const;
6427 /// Return true if any expression is dependent.
6428 bool dependent() const;
6429 /// Returns true if the initializer forms non-rectangular loop.
6430 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6431 /// Returns true if the condition forms non-rectangular loop.
6432 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6433 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6434 unsigned getLoopDependentIdx() const {
6435 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6436 }
6437
6438private:
6439 /// Check the right-hand side of an assignment in the increment
6440 /// expression.
6441 bool checkAndSetIncRHS(Expr *RHS);
6442 /// Helper to set loop counter variable and its initializer.
6443 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6444 bool EmitDiags);
6445 /// Helper to set upper bound.
6446 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6447 SourceRange SR, SourceLocation SL);
6448 /// Helper to set loop increment.
6449 bool setStep(Expr *NewStep, bool Subtract);
6450};
6451
6452bool OpenMPIterationSpaceChecker::dependent() const {
6453 if (!LCDecl) {
6454 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6454, __PRETTY_FUNCTION__))
;
6455 return false;
6456 }
6457 return LCDecl->getType()->isDependentType() ||
6458 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6459 (Step && Step->isValueDependent());
6460}
6461
6462bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6463 Expr *NewLCRefExpr,
6464 Expr *NewLB, bool EmitDiags) {
6465 // State consistency checking to ensure correct usage.
6466 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6467, __PRETTY_FUNCTION__))
6467 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6467, __PRETTY_FUNCTION__))
;
6468 if (!NewLCDecl || !NewLB)
6469 return true;
6470 LCDecl = getCanonicalDecl(NewLCDecl);
6471 LCRef = NewLCRefExpr;
6472 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6473 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6474 if ((Ctor->isCopyOrMoveConstructor() ||
6475 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6476 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6477 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6478 LB = NewLB;
6479 if (EmitDiags)
6480 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6481 return false;
6482}
6483
6484bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6485 llvm::Optional<bool> LessOp,
6486 bool StrictOp, SourceRange SR,
6487 SourceLocation SL) {
6488 // State consistency checking to ensure correct usage.
6489 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6490, __PRETTY_FUNCTION__))
6490 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6490, __PRETTY_FUNCTION__))
;
6491 if (!NewUB)
6492 return true;
6493 UB = NewUB;
6494 if (LessOp)
6495 TestIsLessOp = LessOp;
6496 TestIsStrictOp = StrictOp;
6497 ConditionSrcRange = SR;
6498 ConditionLoc = SL;
6499 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6500 return false;
6501}
6502
6503bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6504 // State consistency checking to ensure correct usage.
6505 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step ==
nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6505, __PRETTY_FUNCTION__))
;
6506 if (!NewStep)
6507 return true;
6508 if (!NewStep->isValueDependent()) {
6509 // Check that the step is integer expression.
6510 SourceLocation StepLoc = NewStep->getBeginLoc();
6511 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6512 StepLoc, getExprAsWritten(NewStep));
6513 if (Val.isInvalid())
6514 return true;
6515 NewStep = Val.get();
6516
6517 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6518 // If test-expr is of form var relational-op b and relational-op is < or
6519 // <= then incr-expr must cause var to increase on each iteration of the
6520 // loop. If test-expr is of form var relational-op b and relational-op is
6521 // > or >= then incr-expr must cause var to decrease on each iteration of
6522 // the loop.
6523 // If test-expr is of form b relational-op var and relational-op is < or
6524 // <= then incr-expr must cause var to decrease on each iteration of the
6525 // loop. If test-expr is of form b relational-op var and relational-op is
6526 // > or >= then incr-expr must cause var to increase on each iteration of
6527 // the loop.
6528 Optional<llvm::APSInt> Result =
6529 NewStep->getIntegerConstantExpr(SemaRef.Context);
6530 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6531 bool IsConstNeg =
6532 Result && Result->isSigned() && (Subtract != Result->isNegative());
6533 bool IsConstPos =
6534 Result && Result->isSigned() && (Subtract == Result->isNegative());
6535 bool IsConstZero = Result && !Result->getBoolValue();
6536
6537 // != with increment is treated as <; != with decrement is treated as >
6538 if (!TestIsLessOp.hasValue())
6539 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6540 if (UB && (IsConstZero ||
6541 (TestIsLessOp.getValue() ?
6542 (IsConstNeg || (IsUnsigned && Subtract)) :
6543 (IsConstPos || (IsUnsigned && !Subtract))))) {
6544 SemaRef.Diag(NewStep->getExprLoc(),
6545 diag::err_omp_loop_incr_not_compatible)
6546 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6547 SemaRef.Diag(ConditionLoc,
6548 diag::note_omp_loop_cond_requres_compatible_incr)
6549 << TestIsLessOp.getValue() << ConditionSrcRange;
6550 return true;
6551 }
6552 if (TestIsLessOp.getValue() == Subtract) {
6553 NewStep =
6554 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6555 .get();
6556 Subtract = !Subtract;
6557 }
6558 }
6559
6560 Step = NewStep;
6561 SubtractStep = Subtract;
6562 return false;
6563}
6564
6565namespace {
6566/// Checker for the non-rectangular loops. Checks if the initializer or
6567/// condition expression references loop counter variable.
6568class LoopCounterRefChecker final
6569 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6570 Sema &SemaRef;
6571 DSAStackTy &Stack;
6572 const ValueDecl *CurLCDecl = nullptr;
6573 const ValueDecl *DepDecl = nullptr;
6574 const ValueDecl *PrevDepDecl = nullptr;
6575 bool IsInitializer = true;
6576 unsigned BaseLoopId = 0;
6577 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6578 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6579 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6580 << (IsInitializer ? 0 : 1);
6581 return false;
6582 }
6583 const auto &&Data = Stack.isLoopControlVariable(VD);
6584 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6585 // The type of the loop iterator on which we depend may not have a random
6586 // access iterator type.
6587 if (Data.first && VD->getType()->isRecordType()) {
6588 SmallString<128> Name;
6589 llvm::raw_svector_ostream OS(Name);
6590 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6591 /*Qualified=*/true);
6592 SemaRef.Diag(E->getExprLoc(),
6593 diag::err_omp_wrong_dependency_iterator_type)
6594 << OS.str();
6595 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6596 return false;
6597 }
6598 if (Data.first &&
6599 (DepDecl || (PrevDepDecl &&
6600 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6601 if (!DepDecl && PrevDepDecl)
6602 DepDecl = PrevDepDecl;
6603 SmallString<128> Name;
6604 llvm::raw_svector_ostream OS(Name);
6605 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6606 /*Qualified=*/true);
6607 SemaRef.Diag(E->getExprLoc(),
6608 diag::err_omp_invariant_or_linear_dependency)
6609 << OS.str();
6610 return false;
6611 }
6612 if (Data.first) {
6613 DepDecl = VD;
6614 BaseLoopId = Data.first;
6615 }
6616 return Data.first;
6617 }
6618
6619public:
6620 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6621 const ValueDecl *VD = E->getDecl();
6622 if (isa<VarDecl>(VD))
6623 return checkDecl(E, VD);
6624 return false;
6625 }
6626 bool VisitMemberExpr(const MemberExpr *E) {
6627 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6628 const ValueDecl *VD = E->getMemberDecl();
6629 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6630 return checkDecl(E, VD);
6631 }
6632 return false;
6633 }
6634 bool VisitStmt(const Stmt *S) {
6635 bool Res = false;
6636 for (const Stmt *Child : S->children())
6637 Res = (Child && Visit(Child)) || Res;
6638 return Res;
6639 }
6640 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6641 const ValueDecl *CurLCDecl, bool IsInitializer,
6642 const ValueDecl *PrevDepDecl = nullptr)
6643 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6644 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6645 unsigned getBaseLoopId() const {
6646 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6646, __PRETTY_FUNCTION__))
;
6647 return BaseLoopId;
6648 }
6649 const ValueDecl *getDepDecl() const {
6650 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 6650, __PRETTY_FUNCTION__))
;
6651 return DepDecl;
6652 }
6653};
6654} // namespace
6655
6656Optional<unsigned>
6657OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6658 bool IsInitializer) {
6659 // Check for the non-rectangular loops.
6660 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6661 DepDecl);
6662 if (LoopStmtChecker.Visit(S)) {
6663 DepDecl = LoopStmtChecker.getDepDecl();
6664 return LoopStmtChecker.getBaseLoopId();
6665 }
6666 return llvm::None;
6667}
6668
6669bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6670 // Check init-expr for canonical loop form and save loop counter
6671 // variable - #Var and its initialization value - #LB.
6672 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6673 // var = lb
6674 // integer-type var = lb
6675 // random-access-iterator-type var = lb
6676 // pointer-type var = lb
6677 //
6678 if (!S) {
6679 if (EmitDiags) {
6680 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6681 }
6682 return true;
6683 }
6684 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6685 if (!ExprTemp->cleanupsHaveSideEffects())
6686 S = ExprTemp->getSubExpr();
6687
6688 InitSrcRange = S->getSourceRange();
6689 if (Expr *E = dyn_cast<Expr>(S))
6690 S = E->IgnoreParens();
6691 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6692 if (BO->getOpcode() == BO_Assign) {
6693 Expr *LHS = BO->getLHS()->IgnoreParens();
6694 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6695 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6696 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6697 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6698 EmitDiags);
6699 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6700 }
6701 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6702 if (ME->isArrow() &&
6703 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6704 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6705 EmitDiags);
6706 }
6707 }
6708 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6709 if (DS->isSingleDecl()) {
6710 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6711 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6712 // Accept non-canonical init form here but emit ext. warning.
6713 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6714 SemaRef.Diag(S->getBeginLoc(),
6715 diag::ext_omp_loop_not_canonical_init)
6716 << S->getSourceRange();
6717 return setLCDeclAndLB(
6718 Var,
6719 buildDeclRefExpr(SemaRef, Var,
6720 Var->getType().getNonReferenceType(),
6721 DS->getBeginLoc()),
6722 Var->getInit(), EmitDiags);
6723 }
6724 }
6725 }
6726 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6727 if (CE->getOperator() == OO_Equal) {
6728 Expr *LHS = CE->getArg(0);
6729 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6730 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6731 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6732 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6733 EmitDiags);
6734 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6735 }
6736 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6737 if (ME->isArrow() &&
6738 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6739 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6740 EmitDiags);
6741 }
6742 }
6743 }
6744
6745 if (dependent() || SemaRef.CurContext->isDependentContext())
6746 return false;
6747 if (EmitDiags) {
6748 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6749 << S->getSourceRange();
6750 }
6751 return true;
6752}
6753
6754/// Ignore parenthesizes, implicit casts, copy constructor and return the
6755/// variable (which may be the loop variable) if possible.
6756static const ValueDecl *getInitLCDecl(const Expr *E) {
6757 if (!E)
6758 return nullptr;
6759 E = getExprAsWritten(E);
6760 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6761 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6762 if ((Ctor->isCopyOrMoveConstructor() ||
6763 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6764 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6765 E = CE->getArg(0)->IgnoreParenImpCasts();
6766 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6767 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6768 return getCanonicalDecl(VD);
6769 }
6770 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6771 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6772 return getCanonicalDecl(ME->getMemberDecl());
6773 return nullptr;
6774}
6775
6776bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6777 // Check test-expr for canonical form, save upper-bound UB, flags for
6778 // less/greater and for strict/non-strict comparison.
6779 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6780 // var relational-op b
6781 // b relational-op var
6782 //
6783 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6784 if (!S) {
6785 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6786 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6787 return true;
6788 }
6789 Condition = S;
6790 S = getExprAsWritten(S);
6791 SourceLocation CondLoc = S->getBeginLoc();
6792 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6793 if (BO->isRelationalOp()) {
6794 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6795 return setUB(BO->getRHS(),
6796 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6797 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6798 BO->getSourceRange(), BO->getOperatorLoc());
6799 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6800 return setUB(BO->getLHS(),
6801 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6802 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6803 BO->getSourceRange(), BO->getOperatorLoc());
6804 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6805 return setUB(
6806 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6807 /*LessOp=*/llvm::None,
6808 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6809 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6810 if (CE->getNumArgs() == 2) {
6811 auto Op = CE->getOperator();
6812 switch (Op) {
6813 case OO_Greater:
6814 case OO_GreaterEqual:
6815 case OO_Less:
6816 case OO_LessEqual:
6817 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6818 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6819 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6820 CE->getOperatorLoc());
6821 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6822 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6823 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6824 CE->getOperatorLoc());
6825 break;
6826 case OO_ExclaimEqual:
6827 if (IneqCondIsCanonical)
6828 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6829 : CE->getArg(0),
6830 /*LessOp=*/llvm::None,
6831 /*StrictOp=*/true, CE->getSourceRange(),
6832 CE->getOperatorLoc());
6833 break;
6834 default:
6835 break;
6836 }
6837 }
6838 }
6839 if (dependent() || SemaRef.CurContext->isDependentContext())
6840 return false;
6841 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6842 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6843 return true;
6844}
6845
6846bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6847 // RHS of canonical loop form increment can be:
6848 // var + incr
6849 // incr + var
6850 // var - incr
6851 //
6852 RHS = RHS->IgnoreParenImpCasts();
6853 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6854 if (BO->isAdditiveOp()) {
6855 bool IsAdd = BO->getOpcode() == BO_Add;
6856 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6857 return setStep(BO->getRHS(), !IsAdd);
6858 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6859 return setStep(BO->getLHS(), /*Subtract=*/false);
6860 }
6861 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6862 bool IsAdd = CE->getOperator() == OO_Plus;
6863 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6864 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6865 return setStep(CE->getArg(1), !IsAdd);
6866 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6867 return setStep(CE->getArg(0), /*Subtract=*/false);
6868 }
6869 }
6870 if (dependent() || SemaRef.CurContext->isDependentContext())
6871 return false;
6872 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6873 << RHS->getSourceRange() << LCDecl;
6874 return true;
6875}
6876
6877bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6878 // Check incr-expr for canonical loop form and return true if it
6879 // does not conform.
6880 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6881 // ++var
6882 // var++
6883 // --var
6884 // var--
6885 // var += incr
6886 // var -= incr
6887 // var = var + incr
6888 // var = incr + var
6889 // var = var - incr
6890 //
6891 if (!S) {
6892 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6893 return true;
6894 }
6895 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6896 if (!ExprTemp->cleanupsHaveSideEffects())
6897 S = ExprTemp->getSubExpr();
6898
6899 IncrementSrcRange = S->getSourceRange();
6900 S = S->IgnoreParens();
6901 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
6902 if (UO->isIncrementDecrementOp() &&
6903 getInitLCDecl(UO->getSubExpr()) == LCDecl)
6904 return setStep(SemaRef
6905 .ActOnIntegerConstant(UO->getBeginLoc(),
6906 (UO->isDecrementOp() ? -1 : 1))
6907 .get(),
6908 /*Subtract=*/false);
6909 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6910 switch (BO->getOpcode()) {
6911 case BO_AddAssign:
6912 case BO_SubAssign:
6913 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6914 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6915 break;
6916 case BO_Assign:
6917 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6918 return checkAndSetIncRHS(BO->getRHS());
6919 break;
6920 default:
6921 break;
6922 }
6923 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6924 switch (CE->getOperator()) {
6925 case OO_PlusPlus:
6926 case OO_MinusMinus:
6927 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6928 return setStep(SemaRef
6929 .ActOnIntegerConstant(
6930 CE->getBeginLoc(),
6931 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6932 .get(),
6933 /*Subtract=*/false);
6934 break;
6935 case OO_PlusEqual:
6936 case OO_MinusEqual:
6937 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6938 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6939 break;
6940 case OO_Equal:
6941 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6942 return checkAndSetIncRHS(CE->getArg(1));
6943 break;
6944 default:
6945 break;
6946 }
6947 }
6948 if (dependent() || SemaRef.CurContext->isDependentContext())
6949 return false;
6950 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6951 << S->getSourceRange() << LCDecl;
6952 return true;
6953}
6954
6955static ExprResult
6956tryBuildCapture(Sema &SemaRef, Expr *Capture,
6957 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6958 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
6959 return Capture;
6960 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
6961 return SemaRef.PerformImplicitConversion(
6962 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
6963 /*AllowExplicit=*/true);
6964 auto I = Captures.find(Capture);
6965 if (I != Captures.end())
6966 return buildCapture(SemaRef, Capture, I->second);
6967 DeclRefExpr *Ref = nullptr;
6968 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
6969 Captures[Capture] = Ref;
6970 return Res;
6971}
6972
6973/// Calculate number of iterations, transforming to unsigned, if number of
6974/// iterations may be larger than the original type.
6975static Expr *
6976calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
6977 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
6978 bool TestIsStrictOp, bool RoundToStep,
6979 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6980 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6981 if (!NewStep.isUsable())
6982 return nullptr;
6983 llvm::APSInt LRes, SRes;
6984 bool IsLowerConst = false, IsStepConst = false;
6985 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
6986 LRes = *Res;
6987 IsLowerConst = true;
6988 }
6989 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
6990 SRes = *Res;
6991 IsStepConst = true;
6992 }
6993 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
6994 ((!TestIsStrictOp && LRes.isNonNegative()) ||
6995 (TestIsStrictOp && LRes.isStrictlyPositive()));
6996 bool NeedToReorganize = false;
6997 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
6998 if (!NoNeedToConvert && IsLowerConst &&
6999 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7000 NoNeedToConvert = true;
7001 if (RoundToStep) {
7002 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7003 ? LRes.getBitWidth()
7004 : SRes.getBitWidth();
7005 LRes = LRes.extend(BW + 1);
7006 LRes.setIsSigned(true);
7007 SRes = SRes.extend(BW + 1);
7008 SRes.setIsSigned(true);
7009 LRes -= SRes;
7010 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7011 LRes = LRes.trunc(BW);
7012 }
7013 if (TestIsStrictOp) {
7014 unsigned BW = LRes.getBitWidth();
7015 LRes = LRes.extend(BW + 1);
7016 LRes.setIsSigned(true);
7017 ++LRes;
7018 NoNeedToConvert =
7019 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7020 // truncate to the original bitwidth.
7021 LRes = LRes.trunc(BW);
7022 }
7023 NeedToReorganize = NoNeedToConvert;
7024 }
7025 llvm::APSInt URes;
7026 bool IsUpperConst = false;
7027 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7028 URes = *Res;
7029 IsUpperConst = true;
7030 }
7031 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7032 (!RoundToStep || IsStepConst)) {
7033 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7034 : URes.getBitWidth();
7035 LRes = LRes.extend(BW + 1);
7036 LRes.setIsSigned(true);
7037 URes = URes.extend(BW + 1);
7038 URes.setIsSigned(true);
7039 URes -= LRes;
7040 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7041 NeedToReorganize = NoNeedToConvert;
7042 }
7043 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7044 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7045 // unsigned.
7046 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7047 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7048 QualType LowerTy = Lower->getType();
7049 QualType UpperTy = Upper->getType();
7050 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7051 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7052 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7053 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7054 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7055 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7056 Upper =
7057 SemaRef
7058 .PerformImplicitConversion(
7059 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7060 CastType, Sema::AA_Converting)
7061 .get();
7062 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7063 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7064 }
7065 }
7066 if (!Lower || !Upper || NewStep.isInvalid())
7067 return nullptr;
7068
7069 ExprResult Diff;
7070 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7071 // 1]).
7072 if (NeedToReorganize) {
7073 Diff = Lower;
7074
7075 if (RoundToStep) {
7076 // Lower - Step
7077 Diff =
7078 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7079 if (!Diff.isUsable())
7080 return nullptr;
7081 }
7082
7083 // Lower - Step [+ 1]
7084 if (TestIsStrictOp)
7085 Diff = SemaRef.BuildBinOp(
7086 S, DefaultLoc, BO_Add, Diff.get(),
7087 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7088 if (!Diff.isUsable())
7089 return nullptr;
7090
7091 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7092 if (!Diff.isUsable())
7093 return nullptr;
7094
7095 // Upper - (Lower - Step [+ 1]).
7096 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7097 if (!Diff.isUsable())
7098 return nullptr;
7099 } else {
7100 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7101
7102 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7103 // BuildBinOp already emitted error, this one is to point user to upper
7104 // and lower bound, and to tell what is passed to 'operator-'.
7105 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7106 << Upper->getSourceRange() << Lower->getSourceRange();
7107 return nullptr;
7108 }
7109
7110 if (!Diff.isUsable())
7111 return nullptr;
7112
7113 // Upper - Lower [- 1]
7114 if (TestIsStrictOp)
7115 Diff = SemaRef.BuildBinOp(
7116 S, DefaultLoc, BO_Sub, Diff.get(),
7117 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7118 if (!Diff.isUsable())
7119 return nullptr;
7120
7121 if (RoundToStep) {
7122 // Upper - Lower [- 1] + Step
7123 Diff =
7124 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7125 if (!Diff.isUsable())
7126 return nullptr;
7127 }
7128 }
7129
7130 // Parentheses (for dumping/debugging purposes only).
7131 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7132 if (!Diff.isUsable())
7133 return nullptr;
7134
7135 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7136 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7137 if (!Diff.isUsable())
7138 return nullptr;
7139
7140 return Diff.get();
7141}
7142
7143/// Build the expression to calculate the number of iterations.
7144Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7145 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7146 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7147 QualType VarType = LCDecl->getType().getNonReferenceType();
7148 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7149 !SemaRef.getLangOpts().CPlusPlus)
7150 return nullptr;
7151 Expr *LBVal = LB;
7152 Expr *UBVal = UB;
7153 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7154 // max(LB(MinVal), LB(MaxVal))
7155 if (InitDependOnLC) {
7156 const LoopIterationSpace &IS =
7157 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7158 InitDependOnLC.getValueOr(
7159 CondDependOnLC.getValueOr(0))];
7160 if (!IS.MinValue || !IS.MaxValue)
7161 return nullptr;
7162 // OuterVar = Min
7163 ExprResult MinValue =
7164 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7165 if (!MinValue.isUsable())
7166 return nullptr;
7167
7168 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7169 IS.CounterVar, MinValue.get());
7170 if (!LBMinVal.isUsable())
7171 return nullptr;
7172 // OuterVar = Min, LBVal
7173 LBMinVal =
7174 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7175 if (!LBMinVal.isUsable())
7176 return nullptr;
7177 // (OuterVar = Min, LBVal)
7178 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7179 if (!LBMinVal.isUsable())
7180 return nullptr;
7181
7182 // OuterVar = Max
7183 ExprResult MaxValue =
7184 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7185 if (!MaxValue.isUsable())
7186 return nullptr;
7187
7188 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7189 IS.CounterVar, MaxValue.get());
7190 if (!LBMaxVal.isUsable())
7191 return nullptr;
7192 // OuterVar = Max, LBVal
7193 LBMaxVal =
7194 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7195 if (!LBMaxVal.isUsable())
7196 return nullptr;
7197 // (OuterVar = Max, LBVal)
7198 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7199 if (!LBMaxVal.isUsable())
7200 return nullptr;
7201
7202 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7203 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7204 if (!LBMin || !LBMax)
7205 return nullptr;
7206 // LB(MinVal) < LB(MaxVal)
7207 ExprResult MinLessMaxRes =
7208 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7209 if (!MinLessMaxRes.isUsable())
7210 return nullptr;
7211 Expr *MinLessMax =
7212 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7213 if (!MinLessMax)
7214 return nullptr;
7215 if (TestIsLessOp.getValue()) {
7216 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7217 // LB(MaxVal))
7218 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7219 MinLessMax, LBMin, LBMax);
7220 if (!MinLB.isUsable())
7221 return nullptr;
7222 LBVal = MinLB.get();
7223 } else {
7224 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7225 // LB(MaxVal))
7226 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7227 MinLessMax, LBMax, LBMin);
7228 if (!MaxLB.isUsable())
7229 return nullptr;
7230 LBVal = MaxLB.get();
7231 }
7232 }
7233 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7234 // min(UB(MinVal), UB(MaxVal))
7235 if (CondDependOnLC) {
7236 const LoopIterationSpace &IS =
7237 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7238 InitDependOnLC.getValueOr(
7239 CondDependOnLC.getValueOr(0))];
7240 if (!IS.MinValue || !IS.MaxValue)
7241 return nullptr;
7242 // OuterVar = Min
7243 ExprResult MinValue =
7244 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7245 if (!MinValue.isUsable())
7246 return nullptr;
7247
7248 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7249 IS.CounterVar, MinValue.get());
7250 if (!UBMinVal.isUsable())
7251 return nullptr;
7252 // OuterVar = Min, UBVal
7253 UBMinVal =
7254 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7255 if (!UBMinVal.isUsable())
7256 return nullptr;
7257 // (OuterVar = Min, UBVal)
7258 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7259 if (!UBMinVal.isUsable())
7260 return nullptr;
7261
7262 // OuterVar = Max
7263 ExprResult MaxValue =
7264 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7265 if (!MaxValue.isUsable())
7266 return nullptr;
7267
7268 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7269 IS.CounterVar, MaxValue.get());
7270 if (!UBMaxVal.isUsable())
7271 return nullptr;
7272 // OuterVar = Max, UBVal
7273 UBMaxVal =
7274 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7275 if (!UBMaxVal.isUsable())
7276 return nullptr;
7277 // (OuterVar = Max, UBVal)
7278 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7279 if (!UBMaxVal.isUsable())
7280 return nullptr;
7281
7282 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7283 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7284 if (!UBMin || !UBMax)
7285 return nullptr;
7286 // UB(MinVal) > UB(MaxVal)
7287 ExprResult MinGreaterMaxRes =
7288 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7289 if (!MinGreaterMaxRes.isUsable())
7290 return nullptr;
7291 Expr *MinGreaterMax =
7292 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7293 if (!MinGreaterMax)
7294 return nullptr;
7295 if (TestIsLessOp.getValue()) {
7296 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7297 // UB(MaxVal))
7298 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7299 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7300 if (!MaxUB.isUsable())
7301 return nullptr;
7302 UBVal = MaxUB.get();
7303 } else {
7304 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7305 // UB(MaxVal))
7306 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7307 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7308 if (!MinUB.isUsable())
7309 return nullptr;
7310 UBVal = MinUB.get();
7311 }
7312 }
7313 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7314 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7315 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7316 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7317 if (!Upper || !Lower)
7318 return nullptr;
7319
7320 ExprResult Diff =
7321 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7322 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7323 if (!Diff.isUsable())
7324 return nullptr;
7325
7326 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7327 QualType Type = Diff.get()->getType();
7328 ASTContext &C = SemaRef.Context;
7329 bool UseVarType = VarType->hasIntegerRepresentation() &&
7330 C.getTypeSize(Type) > C.getTypeSize(VarType);
7331 if (!Type->isIntegerType() || UseVarType) {
7332 unsigned NewSize =
7333 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7334 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7335 : Type->hasSignedIntegerRepresentation();
7336 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7337 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7338 Diff = SemaRef.PerformImplicitConversion(
7339 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7340 if (!Diff.isUsable())
7341 return nullptr;
7342 }
7343 }
7344 if (LimitedType) {
7345 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7346 if (NewSize != C.getTypeSize(Type)) {
7347 if (NewSize < C.getTypeSize(Type)) {
7348 assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast
<void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7348, __PRETTY_FUNCTION__))
;
7349 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7350 << InitSrcRange << ConditionSrcRange;
7351 }
7352 QualType NewType = C.getIntTypeForBitwidth(
7353 NewSize, Type->hasSignedIntegerRepresentation() ||
7354 C.getTypeSize(Type) < NewSize);
7355 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7356 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7357 Sema::AA_Converting, true);
7358 if (!Diff.isUsable())
7359 return nullptr;
7360 }
7361 }
7362 }
7363
7364 return Diff.get();
7365}
7366
7367std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7368 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7369 // Do not build for iterators, they cannot be used in non-rectangular loop
7370 // nests.
7371 if (LCDecl->getType()->isRecordType())
7372 return std::make_pair(nullptr, nullptr);
7373 // If we subtract, the min is in the condition, otherwise the min is in the
7374 // init value.
7375 Expr *MinExpr = nullptr;
7376 Expr *MaxExpr = nullptr;
7377 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7378 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7379 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7380 : CondDependOnLC.hasValue();
7381 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7382 : InitDependOnLC.hasValue();
7383 Expr *Lower =
7384 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7385 Expr *Upper =
7386 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7387 if (!Upper || !Lower)
7388 return std::make_pair(nullptr, nullptr);
7389
7390 if (TestIsLessOp.getValue())
7391 MinExpr = Lower;
7392 else
7393 MaxExpr = Upper;
7394
7395 // Build minimum/maximum value based on number of iterations.
7396 QualType VarType = LCDecl->getType().getNonReferenceType();
7397
7398 ExprResult Diff =
7399 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7400 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7401 if (!Diff.isUsable())
7402 return std::make_pair(nullptr, nullptr);
7403
7404 // ((Upper - Lower [- 1]) / Step) * Step
7405 // Parentheses (for dumping/debugging purposes only).
7406 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7407 if (!Diff.isUsable())
7408 return std::make_pair(nullptr, nullptr);
7409
7410 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7411 if (!NewStep.isUsable())
7412 return std::make_pair(nullptr, nullptr);
7413 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7414 if (!Diff.isUsable())
7415 return std::make_pair(nullptr, nullptr);
7416
7417 // Parentheses (for dumping/debugging purposes only).
7418 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7419 if (!Diff.isUsable())
7420 return std::make_pair(nullptr, nullptr);
7421
7422 // Convert to the ptrdiff_t, if original type is pointer.
7423 if (VarType->isAnyPointerType() &&
7424 !SemaRef.Context.hasSameType(
7425 Diff.get()->getType(),
7426 SemaRef.Context.getUnsignedPointerDiffType())) {
7427 Diff = SemaRef.PerformImplicitConversion(
7428 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7429 Sema::AA_Converting, /*AllowExplicit=*/true);
7430 }
7431 if (!Diff.isUsable())
7432 return std::make_pair(nullptr, nullptr);
7433
7434 if (TestIsLessOp.getValue()) {
7435 // MinExpr = Lower;
7436 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7437 Diff = SemaRef.BuildBinOp(
7438 S, DefaultLoc, BO_Add,
7439 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7440 Diff.get());
7441 if (!Diff.isUsable())
7442 return std::make_pair(nullptr, nullptr);
7443 } else {
7444 // MaxExpr = Upper;
7445 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7446 Diff = SemaRef.BuildBinOp(
7447 S, DefaultLoc, BO_Sub,
7448 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7449 Diff.get());
7450 if (!Diff.isUsable())
7451 return std::make_pair(nullptr, nullptr);
7452 }
7453
7454 // Convert to the original type.
7455 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7456 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7457 Sema::AA_Converting,
7458 /*AllowExplicit=*/true);
7459 if (!Diff.isUsable())
7460 return std::make_pair(nullptr, nullptr);
7461
7462 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7463 if (!Diff.isUsable())
7464 return std::make_pair(nullptr, nullptr);
7465
7466 if (TestIsLessOp.getValue())
7467 MaxExpr = Diff.get();
7468 else
7469 MinExpr = Diff.get();
7470
7471 return std::make_pair(MinExpr, MaxExpr);
7472}
7473
7474Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7475 if (InitDependOnLC || CondDependOnLC)
7476 return Condition;
7477 return nullptr;
7478}
7479
7480Expr *OpenMPIterationSpaceChecker::buildPreCond(
7481 Scope *S, Expr *Cond,
7482 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7483 // Do not build a precondition when the condition/initialization is dependent
7484 // to prevent pessimistic early loop exit.
7485 // TODO: this can be improved by calculating min/max values but not sure that
7486 // it will be very effective.
7487 if (CondDependOnLC || InitDependOnLC)
7488 return SemaRef.PerformImplicitConversion(
7489 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7490 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7491 /*AllowExplicit=*/true).get();
7492
7493 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7494 Sema::TentativeAnalysisScope Trap(SemaRef);
7495
7496 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7497 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7498 if (!NewLB.isUsable() || !NewUB.isUsable())
7499 return nullptr;
7500
7501 ExprResult CondExpr =
7502 SemaRef.BuildBinOp(S, DefaultLoc,
7503 TestIsLessOp.getValue() ?
7504 (TestIsStrictOp ? BO_LT : BO_LE) :
7505 (TestIsStrictOp ? BO_GT : BO_GE),
7506 NewLB.get(), NewUB.get());
7507 if (CondExpr.isUsable()) {
7508 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7509 SemaRef.Context.BoolTy))
7510 CondExpr = SemaRef.PerformImplicitConversion(
7511 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7512 /*AllowExplicit=*/true);
7513 }
7514
7515 // Otherwise use original loop condition and evaluate it in runtime.
7516 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7517}
7518
7519/// Build reference expression to the counter be used for codegen.
7520DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7521 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7522 DSAStackTy &DSA) const {
7523 auto *VD = dyn_cast<VarDecl>(LCDecl);
7524 if (!VD) {
7525 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7526 DeclRefExpr *Ref = buildDeclRefExpr(
7527 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7528 const DSAStackTy::DSAVarData Data =
7529 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7530 // If the loop control decl is explicitly marked as private, do not mark it
7531 // as captured again.
7532 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7533 Captures.insert(std::make_pair(LCRef, Ref));
7534 return Ref;
7535 }
7536 return cast<DeclRefExpr>(LCRef);
7537}
7538
7539Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7540 if (LCDecl && !LCDecl->isInvalidDecl()) {
7541 QualType Type = LCDecl->getType().getNonReferenceType();
7542 VarDecl *PrivateVar = buildVarDecl(
7543 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7544 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7545 isa<VarDecl>(LCDecl)
7546 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7547 : nullptr);
7548 if (PrivateVar->isInvalidDecl())
7549 return nullptr;
7550 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7551 }
7552 return nullptr;
7553}
7554
7555/// Build initialization of the counter to be used for codegen.
7556Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7557
7558/// Build step of the counter be used for codegen.
7559Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7560
7561Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7562 Scope *S, Expr *Counter,
7563 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7564 Expr *Inc, OverloadedOperatorKind OOK) {
7565 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7566 if (!Cnt)
7567 return nullptr;
7568 if (Inc) {
7569 assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7570, __PRETTY_FUNCTION__))
7570 "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7570, __PRETTY_FUNCTION__))
;
7571 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7572 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7573 if (!Cnt)
7574 return nullptr;
7575 }
7576 QualType VarType = LCDecl->getType().getNonReferenceType();
7577 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7578 !SemaRef.getLangOpts().CPlusPlus)
7579 return nullptr;
7580 // Upper - Lower
7581 Expr *Upper = TestIsLessOp.getValue()
7582 ? Cnt
7583 : tryBuildCapture(SemaRef, LB, Captures).get();
7584 Expr *Lower = TestIsLessOp.getValue()
7585 ? tryBuildCapture(SemaRef, LB, Captures).get()
7586 : Cnt;
7587 if (!Upper || !Lower)
7588 return nullptr;
7589
7590 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7591 Step, VarType, /*TestIsStrictOp=*/false,
7592 /*RoundToStep=*/false, Captures);
7593 if (!Diff.isUsable())
7594 return nullptr;
7595
7596 return Diff.get();
7597}
7598} // namespace
7599
7600void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7601 assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7601, __PRETTY_FUNCTION__))
;
7602 assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast
<void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7602, __PRETTY_FUNCTION__))
;
7603 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
7604 if (AssociatedLoops > 0 &&
7605 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
7606 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
7607 OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
7608 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7609 if (ValueDecl *D = ISC.getLoopDecl()) {
7610 auto *VD = dyn_cast<VarDecl>(D);
7611 DeclRefExpr *PrivateRef = nullptr;
7612 if (!VD) {
7613 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7614 VD = Private;
7615 } else {
7616 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7617 /*WithInit=*/false);
7618 VD = cast<VarDecl>(PrivateRef->getDecl());
7619 }
7620 }
7621 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
7622 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
7623 if (LD != D->getCanonicalDecl()) {
7624 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
7625 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7626 MarkDeclarationsReferencedInExpr(
7627 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7628 Var->getType().getNonLValueExprType(Context),
7629 ForLoc, /*RefersToCapture=*/true));
7630 }
7631 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
7632 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7633 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7634 // associated for-loop of a simd construct with just one associated
7635 // for-loop may be listed in a linear clause with a constant-linear-step
7636 // that is the increment of the associated for-loop. The loop iteration
7637 // variable(s) in the associated for-loop(s) of a for or parallel for
7638 // construct may be listed in a private or lastprivate clause.
7639 DSAStackTy::DSAVarData DVar =
7640 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
7641 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7642 // is declared in the loop and it is predetermined as a private.
7643 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7644 OpenMPClauseKind PredeterminedCKind =
7645 isOpenMPSimdDirective(DKind)
7646 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7647 : OMPC_private;
7648 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7649 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7650 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7651 DVar.CKind != OMPC_private))) ||
7652 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7653 DKind == OMPD_master_taskloop ||
7654 DKind == OMPD_parallel_master_taskloop ||
7655 isOpenMPDistributeDirective(DKind)) &&
7656 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7657 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7658 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7659 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7660 << getOpenMPClauseName(DVar.CKind)
7661 << getOpenMPDirectiveName(DKind)
7662 << getOpenMPClauseName(PredeterminedCKind);
7663 if (DVar.RefExpr == nullptr)
7664 DVar.CKind = PredeterminedCKind;
7665 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
7666 /*IsLoopIterVar=*/true);
7667 } else if (LoopDeclRefExpr) {
7668 // Make the loop iteration variable private (for worksharing
7669 // constructs), linear (for simd directives with the only one
7670 // associated loop) or lastprivate (for simd directives with several
7671 // collapsed or ordered loops).
7672 if (DVar.CKind == OMPC_unknown)
7673 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7674 PrivateRef);
7675 }
7676 }
7677 }
7678 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
7679 }
7680}
7681
7682/// Called on a for stmt to check and extract its iteration space
7683/// for further processing (such as collapsing).
7684static bool checkOpenMPIterationSpace(
7685 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7686 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7687 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7688 Expr *OrderedLoopCountExpr,
7689 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7690 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7691 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7692 // OpenMP [2.9.1, Canonical Loop Form]
7693 // for (init-expr; test-expr; incr-expr) structured-block
7694 // for (range-decl: range-expr) structured-block
7695 auto *For = dyn_cast_or_null<ForStmt>(S);
7696 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7697 // Ranged for is supported only in OpenMP 5.0.
7698 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7699 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7700 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7701 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7702 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7703 if (TotalNestedLoopCount > 1) {
7704 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7705 SemaRef.Diag(DSA.getConstructLoc(),
7706 diag::note_omp_collapse_ordered_expr)
7707 << 2 << CollapseLoopCountExpr->getSourceRange()
7708 << OrderedLoopCountExpr->getSourceRange();
7709 else if (CollapseLoopCountExpr)
7710 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7711 diag::note_omp_collapse_ordered_expr)
7712 << 0 << CollapseLoopCountExpr->getSourceRange();
7713 else
7714 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7715 diag::note_omp_collapse_ordered_expr)
7716 << 1 << OrderedLoopCountExpr->getSourceRange();
7717 }
7718 return true;
7719 }
7720 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7721, __PRETTY_FUNCTION__))
7721 "No loop body.")((((For && For->getBody()) || (CXXFor && CXXFor
->getBody())) && "No loop body.") ? static_cast<
void> (0) : __assert_fail ("((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && \"No loop body.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7721, __PRETTY_FUNCTION__))
;
7722
7723 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7724 For ? For->getForLoc() : CXXFor->getForLoc());
7725
7726 // Check init.
7727 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7728 if (ISC.checkAndSetInit(Init))
7729 return true;
7730
7731 bool HasErrors = false;
7732
7733 // Check loop variable's type.
7734 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7735 // OpenMP [2.6, Canonical Loop Form]
7736 // Var is one of the following:
7737 // A variable of signed or unsigned integer type.
7738 // For C++, a variable of a random access iterator type.
7739 // For C, a variable of a pointer type.
7740 QualType VarType = LCDecl->getType().getNonReferenceType();
7741 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7742 !VarType->isPointerType() &&
7743 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7744 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7745 << SemaRef.getLangOpts().CPlusPlus;
7746 HasErrors = true;
7747 }
7748
7749 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7750 // a Construct
7751 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7752 // parallel for construct is (are) private.
7753 // The loop iteration variable in the associated for-loop of a simd
7754 // construct with just one associated for-loop is linear with a
7755 // constant-linear-step that is the increment of the associated for-loop.
7756 // Exclude loop var from the list of variables with implicitly defined data
7757 // sharing attributes.
7758 VarsWithImplicitDSA.erase(LCDecl);
7759
7760 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 7760, __PRETTY_FUNCTION__))
;
7761
7762 // Check test-expr.
7763 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7764
7765 // Check incr-expr.
7766 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7767 }
7768
7769 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7770 return HasErrors;
7771
7772 // Build the loop's iteration space representation.
7773 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7774 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7775 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7776 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7777 (isOpenMPWorksharingDirective(DKind) ||
7778 isOpenMPTaskLoopDirective(DKind) ||
7779 isOpenMPDistributeDirective(DKind)),
7780 Captures);
7781 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7782 ISC.buildCounterVar(Captures, DSA);
7783 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7784 ISC.buildPrivateCounterVar();
7785 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7786 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7787 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7788 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7789 ISC.getConditionSrcRange();
7790 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7791 ISC.getIncrementSrcRange();
7792 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7793 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7794 ISC.isStrictTestOp();
7795 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7796 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7797 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7798 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7799 ISC.buildFinalCondition(DSA.getCurScope());
7800 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7801 ISC.doesInitDependOnLC();
7802 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7803 ISC.doesCondDependOnLC();
7804 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7805 ISC.getLoopDependentIdx();
7806
7807 HasErrors |=
7808 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7809 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7810 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7811 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7812 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7813 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7814 if (!HasErrors && DSA.isOrderedRegion()) {
7815 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7816 if (CurrentNestedLoopCount <
7817 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7818 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7819 CurrentNestedLoopCount,
7820 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7821 DSA.getOrderedRegionParam().second->setLoopCounter(
7822 CurrentNestedLoopCount,
7823 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7824 }
7825 }
7826 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7827 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7828 // Erroneous case - clause has some problems.
7829 continue;
7830 }
7831 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7832 Pair.second.size() <= CurrentNestedLoopCount) {
7833 // Erroneous case - clause has some problems.
7834 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7835 continue;
7836 }
7837 Expr *CntValue;
7838 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7839 CntValue = ISC.buildOrderedLoopData(
7840 DSA.getCurScope(),
7841 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7842 Pair.first->getDependencyLoc());
7843 else
7844 CntValue = ISC.buildOrderedLoopData(
7845 DSA.getCurScope(),
7846 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7847 Pair.first->getDependencyLoc(),
7848 Pair.second[CurrentNestedLoopCount].first,
7849 Pair.second[CurrentNestedLoopCount].second);
7850 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7851 }
7852 }
7853
7854 return HasErrors;
7855}
7856
7857/// Build 'VarRef = Start.
7858static ExprResult
7859buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7860 ExprResult Start, bool IsNonRectangularLB,
7861 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7862 // Build 'VarRef = Start.
7863 ExprResult NewStart = IsNonRectangularLB
7864 ? Start.get()
7865 : tryBuildCapture(SemaRef, Start.get(), Captures);
7866 if (!NewStart.isUsable())
7867 return ExprError();
7868 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7869 VarRef.get()->getType())) {
7870 NewStart = SemaRef.PerformImplicitConversion(
7871 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7872 /*AllowExplicit=*/true);
7873 if (!NewStart.isUsable())
7874 return ExprError();
7875 }
7876
7877 ExprResult Init =
7878 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7879 return Init;
7880}
7881
7882/// Build 'VarRef = Start + Iter * Step'.
7883static ExprResult buildCounterUpdate(
7884 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7885 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7886 bool IsNonRectangularLB,
7887 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7888 // Add parentheses (for debugging purposes only).
7889 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7890 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7891 !Step.isUsable())
7892 return ExprError();
7893
7894 ExprResult NewStep = Step;
7895 if (Captures)
7896 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
7897 if (NewStep.isInvalid())
7898 return ExprError();
7899 ExprResult Update =
7900 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
7901 if (!Update.isUsable())
7902 return ExprError();
7903
7904 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
7905 // 'VarRef = Start (+|-) Iter * Step'.
7906 if (!Start.isUsable())
7907 return ExprError();
7908 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
7909 if (!NewStart.isUsable())
7910 return ExprError();
7911 if (Captures && !IsNonRectangularLB)
7912 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
7913 if (NewStart.isInvalid())
7914 return ExprError();
7915
7916 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
7917 ExprResult SavedUpdate = Update;
7918 ExprResult UpdateVal;
7919 if (VarRef.get()->getType()->isOverloadableType() ||
7920 NewStart.get()->getType()->isOverloadableType() ||
7921 Update.get()->getType()->isOverloadableType()) {
7922 Sema::TentativeAnalysisScope Trap(SemaRef);
7923
7924 Update =
7925 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7926 if (Update.isUsable()) {
7927 UpdateVal =
7928 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7929 VarRef.get(), SavedUpdate.get());
7930 if (UpdateVal.isUsable()) {
7931 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
7932 UpdateVal.get());
7933 }
7934 }
7935 }
7936
7937 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
7938 if (!Update.isUsable() || !UpdateVal.isUsable()) {
7939 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7940 NewStart.get(), SavedUpdate.get());
7941 if (!Update.isUsable())
7942 return ExprError();
7943
7944 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
7945 VarRef.get()->getType())) {
7946 Update = SemaRef.PerformImplicitConversion(
7947 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
7948 if (!Update.isUsable())
7949 return ExprError();
7950 }
7951
7952 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
7953 }
7954 return Update;
7955}
7956
7957/// Convert integer expression \a E to make it have at least \a Bits
7958/// bits.
7959static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
7960 if (E == nullptr)
7961 return ExprError();
7962 ASTContext &C = SemaRef.Context;
7963 QualType OldType = E->getType();
7964 unsigned HasBits = C.getTypeSize(OldType);
7965 if (HasBits >= Bits)
7966 return ExprResult(E);
7967 // OK to convert to signed, because new type has more bits than old.
7968 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
7969 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
7970 true);
7971}
7972
7973/// Check if the given expression \a E is a constant integer that fits
7974/// into \a Bits bits.
7975static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
7976 if (E == nullptr)
7977 return false;
7978 if (Optional<llvm::APSInt> Result =
7979 E->getIntegerConstantExpr(SemaRef.Context))
7980 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
7981 return false;
7982}
7983
7984/// Build preinits statement for the given declarations.
7985static Stmt *buildPreInits(ASTContext &Context,
7986 MutableArrayRef<Decl *> PreInits) {
7987 if (!PreInits.empty()) {
7988 return new (Context) DeclStmt(
7989 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
7990 SourceLocation(), SourceLocation());
7991 }
7992 return nullptr;
7993}
7994
7995/// Build preinits statement for the given declarations.
7996static Stmt *
7997buildPreInits(ASTContext &Context,
7998 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7999 if (!Captures.empty()) {
8000 SmallVector<Decl *, 16> PreInits;
8001 for (const auto &Pair : Captures)
8002 PreInits.push_back(Pair.second->getDecl());
8003 return buildPreInits(Context, PreInits);
8004 }
8005 return nullptr;
8006}
8007
8008/// Build postupdate expression for the given list of postupdates expressions.
8009static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8010 Expr *PostUpdate = nullptr;
8011 if (!PostUpdates.empty()) {
8012 for (Expr *E : PostUpdates) {
8013 Expr *ConvE = S.BuildCStyleCastExpr(
8014 E->getExprLoc(),
8015 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8016 E->getExprLoc(), E)
8017 .get();
8018 PostUpdate = PostUpdate
8019 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8020 PostUpdate, ConvE)
8021 .get()
8022 : ConvE;
8023 }
8024 }
8025 return PostUpdate;
8026}
8027
8028/// Called on a for stmt to check itself and nested loops (if any).
8029/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8030/// number of collapsed loops otherwise.
8031static unsigned
8032checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8033 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8034 DSAStackTy &DSA,
8035 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8036 OMPLoopDirective::HelperExprs &Built) {
8037 unsigned NestedLoopCount = 1;
8038 if (CollapseLoopCountExpr) {
8039 // Found 'collapse' clause - calculate collapse number.
8040 Expr::EvalResult Result;
8041 if (!CollapseLoopCountExpr->isValueDependent() &&
8042 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8043 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8044 } else {
8045 Built.clear(/*Size=*/1);
8046 return 1;
8047 }
8048 }
8049 unsigned OrderedLoopCount = 1;
8050 if (OrderedLoopCountExpr) {
8051 // Found 'ordered' clause - calculate collapse number.
8052 Expr::EvalResult EVResult;
8053 if (!OrderedLoopCountExpr->isValueDependent() &&
8054 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8055 SemaRef.getASTContext())) {
8056 llvm::APSInt Result = EVResult.Val.getInt();
8057 if (Result.getLimitedValue() < NestedLoopCount) {
8058 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8059 diag::err_omp_wrong_ordered_loop_count)
8060 << OrderedLoopCountExpr->getSourceRange();
8061 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8062 diag::note_collapse_loop_count)
8063 << CollapseLoopCountExpr->getSourceRange();
8064 }
8065 OrderedLoopCount = Result.getLimitedValue();
8066 } else {
8067 Built.clear(/*Size=*/1);
8068 return 1;
8069 }
8070 }
8071 // This is helper routine for loop directives (e.g., 'for', 'simd',
8072 // 'for simd', etc.).
8073 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8074 SmallVector<LoopIterationSpace, 4> IterSpaces(
8075 std::max(OrderedLoopCount, NestedLoopCount));
8076 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8077 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8078 if (checkOpenMPIterationSpace(
8079 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8080 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8081 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8082 return 0;
8083 // Move on to the next nested for loop, or to the loop body.
8084 // OpenMP [2.8.1, simd construct, Restrictions]
8085 // All loops associated with the construct must be perfectly nested; that
8086 // is, there must be no intervening code nor any OpenMP directive between
8087 // any two loops.
8088 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8089 CurStmt = For->getBody();
8090 } else {
8091 assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8092, __PRETTY_FUNCTION__))
8092 "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8092, __PRETTY_FUNCTION__))
;
8093 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8094 }
8095 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8096 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8097 }
8098 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8099 if (checkOpenMPIterationSpace(
8100 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8101 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8102 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8103 return 0;
8104 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8105 // Handle initialization of captured loop iterator variables.
8106 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8107 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8108 Captures[DRE] = DRE;
8109 }
8110 }
8111 // Move on to the next nested for loop, or to the loop body.
8112 // OpenMP [2.8.1, simd construct, Restrictions]
8113 // All loops associated with the construct must be perfectly nested; that
8114 // is, there must be no intervening code nor any OpenMP directive between
8115 // any two loops.
8116 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8117 CurStmt = For->getBody();
8118 } else {
8119 assert(isa<CXXForRangeStmt>(CurStmt) &&((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8120, __PRETTY_FUNCTION__))
8120 "Expected canonical for or range-based for loops.")((isa<CXXForRangeStmt>(CurStmt) && "Expected canonical for or range-based for loops."
) ? static_cast<void> (0) : __assert_fail ("isa<CXXForRangeStmt>(CurStmt) && \"Expected canonical for or range-based for loops.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8120, __PRETTY_FUNCTION__))
;
8121 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8122 }
8123 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8124 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8125 }
8126
8127 Built.clear(/* size */ NestedLoopCount);
8128
8129 if (SemaRef.CurContext->isDependentContext())
8130 return NestedLoopCount;
8131
8132 // An example of what is generated for the following code:
8133 //
8134 // #pragma omp simd collapse(2) ordered(2)
8135 // for (i = 0; i < NI; ++i)
8136 // for (k = 0; k < NK; ++k)
8137 // for (j = J0; j < NJ; j+=2) {
8138 // <loop body>
8139 // }
8140 //
8141 // We generate the code below.
8142 // Note: the loop body may be outlined in CodeGen.
8143 // Note: some counters may be C++ classes, operator- is used to find number of
8144 // iterations and operator+= to calculate counter value.
8145 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8146 // or i64 is currently supported).
8147 //
8148 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8149 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8150 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8151 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8152 // // similar updates for vars in clauses (e.g. 'linear')
8153 // <loop body (using local i and j)>
8154 // }
8155 // i = NI; // assign final values of counters
8156 // j = NJ;
8157 //
8158
8159 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8160 // the iteration counts of the collapsed for loops.
8161 // Precondition tests if there is at least one iteration (all conditions are
8162 // true).
8163 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8164 Expr *N0 = IterSpaces[0].NumIterations;
8165 ExprResult LastIteration32 =
8166 widenIterationCount(/*Bits=*/32,
8167 SemaRef
8168 .PerformImplicitConversion(
8169 N0->IgnoreImpCasts(), N0->getType(),
8170 Sema::AA_Converting, /*AllowExplicit=*/true)
8171 .get(),
8172 SemaRef);
8173 ExprResult LastIteration64 = widenIterationCount(
8174 /*Bits=*/64,
8175 SemaRef
8176 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8177 Sema::AA_Converting,
8178 /*AllowExplicit=*/true)
8179 .get(),
8180 SemaRef);
8181
8182 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8183 return NestedLoopCount;
8184
8185 ASTContext &C = SemaRef.Context;
8186 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8187
8188 Scope *CurScope = DSA.getCurScope();
8189 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8190 if (PreCond.isUsable()) {
8191 PreCond =
8192 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8193 PreCond.get(), IterSpaces[Cnt].PreCond);
8194 }
8195 Expr *N = IterSpaces[Cnt].NumIterations;
8196 SourceLocation Loc = N->getExprLoc();
8197 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8198 if (LastIteration32.isUsable())
8199 LastIteration32 = SemaRef.BuildBinOp(
8200 CurScope, Loc, BO_Mul, LastIteration32.get(),
8201 SemaRef
8202 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8203 Sema::AA_Converting,
8204 /*AllowExplicit=*/true)
8205 .get());
8206 if (LastIteration64.isUsable())
8207 LastIteration64 = SemaRef.BuildBinOp(
8208 CurScope, Loc, BO_Mul, LastIteration64.get(),
8209 SemaRef
8210 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8211 Sema::AA_Converting,
8212 /*AllowExplicit=*/true)
8213 .get());
8214 }
8215
8216 // Choose either the 32-bit or 64-bit version.
8217 ExprResult LastIteration = LastIteration64;
8218 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8219 (LastIteration32.isUsable() &&
8220 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8221 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8222 fitsInto(
8223 /*Bits=*/32,
8224 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8225 LastIteration64.get(), SemaRef))))
8226 LastIteration = LastIteration32;
8227 QualType VType = LastIteration.get()->getType();
8228 QualType RealVType = VType;
8229 QualType StrideVType = VType;
8230 if (isOpenMPTaskLoopDirective(DKind)) {
8231 VType =
8232 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8233 StrideVType =
8234 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8235 }
8236
8237 if (!LastIteration.isUsable())
8238 return 0;
8239
8240 // Save the number of iterations.
8241 ExprResult NumIterations = LastIteration;
8242 {
8243 LastIteration = SemaRef.BuildBinOp(
8244 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8245 LastIteration.get(),
8246 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8247 if (!LastIteration.isUsable())
8248 return 0;
8249 }
8250
8251 // Calculate the last iteration number beforehand instead of doing this on
8252 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8253 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
8254 ExprResult CalcLastIteration;
8255 if (!IsConstant) {
8256 ExprResult SaveRef =
8257 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8258 LastIteration = SaveRef;
8259
8260 // Prepare SaveRef + 1.
8261 NumIterations = SemaRef.BuildBinOp(
8262 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8263 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8264 if (!NumIterations.isUsable())
8265 return 0;
8266 }
8267
8268 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8269
8270 // Build variables passed into runtime, necessary for worksharing directives.
8271 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8272 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8273 isOpenMPDistributeDirective(DKind)) {
8274 // Lower bound variable, initialized with zero.
8275 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8276 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8277 SemaRef.AddInitializerToDecl(LBDecl,
8278 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8279 /*DirectInit*/ false);
8280
8281 // Upper bound variable, initialized with last iteration number.
8282 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8283 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8284 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8285 /*DirectInit*/ false);
8286
8287 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8288 // This will be used to implement clause 'lastprivate'.
8289 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8290 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8291 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8292 SemaRef.AddInitializerToDecl(ILDecl,
8293 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8294 /*DirectInit*/ false);
8295
8296 // Stride variable returned by runtime (we initialize it to 1 by default).
8297 VarDecl *STDecl =
8298 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8299 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8300 SemaRef.AddInitializerToDecl(STDecl,
8301 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8302 /*DirectInit*/ false);
8303
8304 // Build expression: UB = min(UB, LastIteration)
8305 // It is necessary for CodeGen of directives with static scheduling.
8306 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8307 UB.get(), LastIteration.get());
8308 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8309 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8310 LastIteration.get(), UB.get());
8311 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8312 CondOp.get());
8313 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8314
8315 // If we have a combined directive that combines 'distribute', 'for' or
8316 // 'simd' we need to be able to access the bounds of the schedule of the
8317 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8318 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8319 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8320 // Lower bound variable, initialized with zero.
8321 VarDecl *CombLBDecl =
8322 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8323 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8324 SemaRef.AddInitializerToDecl(
8325 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8326 /*DirectInit*/ false);
8327
8328 // Upper bound variable, initialized with last iteration number.
8329 VarDecl *CombUBDecl =
8330 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8331 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8332 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8333 /*DirectInit*/ false);
8334
8335 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8336 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8337 ExprResult CombCondOp =
8338 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8339 LastIteration.get(), CombUB.get());
8340 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8341 CombCondOp.get());
8342 CombEUB =
8343 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8344
8345 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8346 // We expect to have at least 2 more parameters than the 'parallel'
8347 // directive does - the lower and upper bounds of the previous schedule.
8348 assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8349, __PRETTY_FUNCTION__))
8349 "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8349, __PRETTY_FUNCTION__))
;
8350
8351 // Set the proper type for the bounds given what we learned from the
8352 // enclosed loops.
8353 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8354 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8355
8356 // Previous lower and upper bounds are obtained from the region
8357 // parameters.
8358 PrevLB =
8359 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8360 PrevUB =
8361 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8362 }
8363 }
8364
8365 // Build the iteration variable and its initialization before loop.
8366 ExprResult IV;
8367 ExprResult Init, CombInit;
8368 {
8369 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8370 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8371 Expr *RHS =
8372 (isOpenMPWorksharingDirective(DKind) ||
8373 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8374 ? LB.get()
8375 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8376 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8377 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8378
8379 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8380 Expr *CombRHS =
8381 (isOpenMPWorksharingDirective(DKind) ||
8382 isOpenMPTaskLoopDirective(DKind) ||
8383 isOpenMPDistributeDirective(DKind))
8384 ? CombLB.get()
8385 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8386 CombInit =
8387 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8388 CombInit =
8389 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8390 }
8391 }
8392
8393 bool UseStrictCompare =
8394 RealVType->hasUnsignedIntegerRepresentation() &&
8395 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8396 return LIS.IsStrictCompare;
8397 });
8398 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8399 // unsigned IV)) for worksharing loops.
8400 SourceLocation CondLoc = AStmt->getBeginLoc();
8401 Expr *BoundUB = UB.get();
8402 if (UseStrictCompare) {
8403 BoundUB =
8404 SemaRef
8405 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8406 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8407 .get();
8408 BoundUB =
8409 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8410 }
8411 ExprResult Cond =
8412 (isOpenMPWorksharingDirective(DKind) ||
8413 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8414 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8415 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8416 BoundUB)
8417 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8418 NumIterations.get());
8419 ExprResult CombDistCond;
8420 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8421 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8422 NumIterations.get());
8423 }
8424
8425 ExprResult CombCond;
8426 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8427 Expr *BoundCombUB = CombUB.get();
8428 if (UseStrictCompare) {
8429 BoundCombUB =
8430 SemaRef
8431 .BuildBinOp(
8432 CurScope, CondLoc, BO_Add, BoundCombUB,
8433 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8434 .get();
8435 BoundCombUB =
8436 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8437 .get();
8438 }
8439 CombCond =
8440 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8441 IV.get(), BoundCombUB);
8442 }
8443 // Loop increment (IV = IV + 1)
8444 SourceLocation IncLoc = AStmt->getBeginLoc();
8445 ExprResult Inc =
8446 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8447 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8448 if (!Inc.isUsable())
8449 return 0;
8450 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8451 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8452 if (!Inc.isUsable())
8453 return 0;
8454
8455 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8456 // Used for directives with static scheduling.
8457 // In combined construct, add combined version that use CombLB and CombUB
8458 // base variables for the update
8459 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8460 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8461 isOpenMPDistributeDirective(DKind)) {
8462 // LB + ST
8463 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8464 if (!NextLB.isUsable())
8465 return 0;
8466 // LB = LB + ST
8467 NextLB =
8468 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8469 NextLB =
8470 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8471 if (!NextLB.isUsable())
8472 return 0;
8473 // UB + ST
8474 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8475 if (!NextUB.isUsable())
8476 return 0;
8477 // UB = UB + ST
8478 NextUB =
8479 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8480 NextUB =
8481 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8482 if (!NextUB.isUsable())
8483 return 0;
8484 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8485 CombNextLB =
8486 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8487 if (!NextLB.isUsable())
8488 return 0;
8489 // LB = LB + ST
8490 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8491 CombNextLB.get());
8492 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8493 /*DiscardedValue*/ false);
8494 if (!CombNextLB.isUsable())
8495 return 0;
8496 // UB + ST
8497 CombNextUB =
8498 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8499 if (!CombNextUB.isUsable())
8500 return 0;
8501 // UB = UB + ST
8502 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8503 CombNextUB.get());
8504 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8505 /*DiscardedValue*/ false);
8506 if (!CombNextUB.isUsable())
8507 return 0;
8508 }
8509 }
8510
8511 // Create increment expression for distribute loop when combined in a same
8512 // directive with for as IV = IV + ST; ensure upper bound expression based
8513 // on PrevUB instead of NumIterations - used to implement 'for' when found
8514 // in combination with 'distribute', like in 'distribute parallel for'
8515 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8516 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8517 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8518 DistCond = SemaRef.BuildBinOp(
8519 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8520 assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8520, __PRETTY_FUNCTION__))
;
8521
8522 DistInc =
8523 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8524 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8524, __PRETTY_FUNCTION__))
;
8525 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8526 DistInc.get());
8527 DistInc =
8528 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8529 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8529, __PRETTY_FUNCTION__))
;
8530
8531 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8532 // construct
8533 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8534 ExprResult IsUBGreater =
8535 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8536 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8537 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8538 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8539 CondOp.get());
8540 PrevEUB =
8541 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8542
8543 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8544 // parallel for is in combination with a distribute directive with
8545 // schedule(static, 1)
8546 Expr *BoundPrevUB = PrevUB.get();
8547 if (UseStrictCompare) {
8548 BoundPrevUB =
8549 SemaRef
8550 .BuildBinOp(
8551 CurScope, CondLoc, BO_Add, BoundPrevUB,
8552 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8553 .get();
8554 BoundPrevUB =
8555 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8556 .get();
8557 }
8558 ParForInDistCond =
8559 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8560 IV.get(), BoundPrevUB);
8561 }
8562
8563 // Build updates and final values of the loop counters.
8564 bool HasErrors = false;
8565 Built.Counters.resize(NestedLoopCount);
8566 Built.Inits.resize(NestedLoopCount);
8567 Built.Updates.resize(NestedLoopCount);
8568 Built.Finals.resize(NestedLoopCount);
8569 Built.DependentCounters.resize(NestedLoopCount);
8570 Built.DependentInits.resize(NestedLoopCount);
8571 Built.FinalsConditions.resize(NestedLoopCount);
8572 {
8573 // We implement the following algorithm for obtaining the
8574 // original loop iteration variable values based on the
8575 // value of the collapsed loop iteration variable IV.
8576 //
8577 // Let n+1 be the number of collapsed loops in the nest.
8578 // Iteration variables (I0, I1, .... In)
8579 // Iteration counts (N0, N1, ... Nn)
8580 //
8581 // Acc = IV;
8582 //
8583 // To compute Ik for loop k, 0 <= k <= n, generate:
8584 // Prod = N(k+1) * N(k+2) * ... * Nn;
8585 // Ik = Acc / Prod;
8586 // Acc -= Ik * Prod;
8587 //
8588 ExprResult Acc = IV;
8589 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8590 LoopIterationSpace &IS = IterSpaces[Cnt];
8591 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8592 ExprResult Iter;
8593
8594 // Compute prod
8595 ExprResult Prod =
8596 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8597 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8598 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8599 IterSpaces[K].NumIterations);
8600
8601 // Iter = Acc / Prod
8602 // If there is at least one more inner loop to avoid
8603 // multiplication by 1.
8604 if (Cnt + 1 < NestedLoopCount)
8605 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8606 Acc.get(), Prod.get());
8607 else
8608 Iter = Acc;
8609 if (!Iter.isUsable()) {
8610 HasErrors = true;
8611 break;
8612 }
8613
8614 // Update Acc:
8615 // Acc -= Iter * Prod
8616 // Check if there is at least one more inner loop to avoid
8617 // multiplication by 1.
8618 if (Cnt + 1 < NestedLoopCount)
8619 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8620 Iter.get(), Prod.get());
8621 else
8622 Prod = Iter;
8623 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8624 Acc.get(), Prod.get());
8625
8626 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8627 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8628 DeclRefExpr *CounterVar = buildDeclRefExpr(
8629 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8630 /*RefersToCapture=*/true);
8631 ExprResult Init =
8632 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8633 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8634 if (!Init.isUsable()) {
8635 HasErrors = true;
8636 break;
8637 }
8638 ExprResult Update = buildCounterUpdate(
8639 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8640 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8641 if (!Update.isUsable()) {
8642 HasErrors = true;
8643 break;
8644 }
8645
8646 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8647 ExprResult Final =
8648 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8649 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8650 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8651 if (!Final.isUsable()) {
8652 HasErrors = true;
8653 break;
8654 }
8655
8656 if (!Update.isUsable() || !Final.isUsable()) {
8657 HasErrors = true;
8658 break;
8659 }
8660 // Save results
8661 Built.Counters[Cnt] = IS.CounterVar;
8662 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8663 Built.Inits[Cnt] = Init.get();
8664 Built.Updates[Cnt] = Update.get();
8665 Built.Finals[Cnt] = Final.get();
8666 Built.DependentCounters[Cnt] = nullptr;
8667 Built.DependentInits[Cnt] = nullptr;
8668 Built.FinalsConditions[Cnt] = nullptr;
8669 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8670 Built.DependentCounters[Cnt] =
8671 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8672 Built.DependentInits[Cnt] =
8673 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8674 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8675 }
8676 }
8677 }
8678
8679 if (HasErrors)
8680 return 0;
8681
8682 // Save results
8683 Built.IterationVarRef = IV.get();
8684 Built.LastIteration = LastIteration.get();
8685 Built.NumIterations = NumIterations.get();
8686 Built.CalcLastIteration = SemaRef
8687 .ActOnFinishFullExpr(CalcLastIteration.get(),
8688 /*DiscardedValue=*/false)
8689 .get();
8690 Built.PreCond = PreCond.get();
8691 Built.PreInits = buildPreInits(C, Captures);
8692 Built.Cond = Cond.get();
8693 Built.Init = Init.get();
8694 Built.Inc = Inc.get();
8695 Built.LB = LB.get();
8696 Built.UB = UB.get();
8697 Built.IL = IL.get();
8698 Built.ST = ST.get();
8699 Built.EUB = EUB.get();
8700 Built.NLB = NextLB.get();
8701 Built.NUB = NextUB.get();
8702 Built.PrevLB = PrevLB.get();
8703 Built.PrevUB = PrevUB.get();
8704 Built.DistInc = DistInc.get();
8705 Built.PrevEUB = PrevEUB.get();
8706 Built.DistCombinedFields.LB = CombLB.get();
8707 Built.DistCombinedFields.UB = CombUB.get();
8708 Built.DistCombinedFields.EUB = CombEUB.get();
8709 Built.DistCombinedFields.Init = CombInit.get();
8710 Built.DistCombinedFields.Cond = CombCond.get();
8711 Built.DistCombinedFields.NLB = CombNextLB.get();
8712 Built.DistCombinedFields.NUB = CombNextUB.get();
8713 Built.DistCombinedFields.DistCond = CombDistCond.get();
8714 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8715
8716 return NestedLoopCount;
8717}
8718
8719static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8720 auto CollapseClauses =
8721 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8722 if (CollapseClauses.begin() != CollapseClauses.end())
8723 return (*CollapseClauses.begin())->getNumForLoops();
8724 return nullptr;
8725}
8726
8727static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8728 auto OrderedClauses =
8729 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8730 if (OrderedClauses.begin() != OrderedClauses.end())
8731 return (*OrderedClauses.begin())->getNumForLoops();
8732 return nullptr;
8733}
8734
8735static bool checkSimdlenSafelenSpecified(Sema &S,
8736 const ArrayRef<OMPClause *> Clauses) {
8737 const OMPSafelenClause *Safelen = nullptr;
8738 const OMPSimdlenClause *Simdlen = nullptr;
8739
8740 for (const OMPClause *Clause : Clauses) {
8741 if (Clause->getClauseKind() == OMPC_safelen)
8742 Safelen = cast<OMPSafelenClause>(Clause);
8743 else if (Clause->getClauseKind() == OMPC_simdlen)
8744 Simdlen = cast<OMPSimdlenClause>(Clause);
8745 if (Safelen && Simdlen)
8746 break;
8747 }
8748
8749 if (Simdlen && Safelen) {
8750 const Expr *SimdlenLength = Simdlen->getSimdlen();
8751 const Expr *SafelenLength = Safelen->getSafelen();
8752 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8753 SimdlenLength->isInstantiationDependent() ||
8754 SimdlenLength->containsUnexpandedParameterPack())
8755 return false;
8756 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8757 SafelenLength->isInstantiationDependent() ||
8758 SafelenLength->containsUnexpandedParameterPack())
8759 return false;
8760 Expr::EvalResult SimdlenResult, SafelenResult;
8761 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8762 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8763 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8764 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8765 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8766 // If both simdlen and safelen clauses are specified, the value of the
8767 // simdlen parameter must be less than or equal to the value of the safelen
8768 // parameter.
8769 if (SimdlenRes > SafelenRes) {
8770 S.Diag(SimdlenLength->getExprLoc(),
8771 diag::err_omp_wrong_simdlen_safelen_values)
8772 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8773 return true;
8774 }
8775 }
8776 return false;
8777}
8778
8779StmtResult
8780Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8781 SourceLocation StartLoc, SourceLocation EndLoc,
8782 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8783 if (!AStmt)
8784 return StmtError();
8785
8786 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8786, __PRETTY_FUNCTION__))
;
8787 OMPLoopDirective::HelperExprs B;
8788 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8789 // define the nested loops number.
8790 unsigned NestedLoopCount = checkOpenMPLoop(
8791 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8792 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8793 if (NestedLoopCount == 0)
8794 return StmtError();
8795
8796 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8797, __PRETTY_FUNCTION__))
8797 "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8797, __PRETTY_FUNCTION__))
;
8798
8799 if (!CurContext->isDependentContext()) {
8800 // Finalize the clauses that need pre-built expressions for CodeGen.
8801 for (OMPClause *C : Clauses) {
8802 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8803 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8804 B.NumIterations, *this, CurScope,
8805 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8806 return StmtError();
8807 }
8808 }
8809
8810 if (checkSimdlenSafelenSpecified(*this, Clauses))
8811 return StmtError();
8812
8813 setFunctionHasBranchProtectedScope();
8814 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8815 Clauses, AStmt, B);
8816}
8817
8818StmtResult
8819Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8820 SourceLocation StartLoc, SourceLocation EndLoc,
8821 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8822 if (!AStmt)
8823 return StmtError();
8824
8825 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8825, __PRETTY_FUNCTION__))
;
8826 OMPLoopDirective::HelperExprs B;
8827 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8828 // define the nested loops number.
8829 unsigned NestedLoopCount = checkOpenMPLoop(
8830 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8831 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8832 if (NestedLoopCount == 0)
8833 return StmtError();
8834
8835 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8836, __PRETTY_FUNCTION__))
8836 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8836, __PRETTY_FUNCTION__))
;
8837
8838 if (!CurContext->isDependentContext()) {
8839 // Finalize the clauses that need pre-built expressions for CodeGen.
8840 for (OMPClause *C : Clauses) {
8841 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8842 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8843 B.NumIterations, *this, CurScope,
8844 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8845 return StmtError();
8846 }
8847 }
8848
8849 setFunctionHasBranchProtectedScope();
8850 return OMPForDirective::Create(
8851 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8852 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8853}
8854
8855StmtResult Sema::ActOnOpenMPForSimdDirective(
8856 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8857 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8858 if (!AStmt)
8859 return StmtError();
8860
8861 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8861, __PRETTY_FUNCTION__))
;
8862 OMPLoopDirective::HelperExprs B;
8863 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8864 // define the nested loops number.
8865 unsigned NestedLoopCount =
8866 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8867 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
8868 VarsWithImplicitDSA, B);
8869 if (NestedLoopCount == 0)
8870 return StmtError();
8871
8872 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8873, __PRETTY_FUNCTION__))
8873 "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8873, __PRETTY_FUNCTION__))
;
8874
8875 if (!CurContext->isDependentContext()) {
8876 // Finalize the clauses that need pre-built expressions for CodeGen.
8877 for (OMPClause *C : Clauses) {
8878 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8879 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8880 B.NumIterations, *this, CurScope,
8881 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8882 return StmtError();
8883 }
8884 }
8885
8886 if (checkSimdlenSafelenSpecified(*this, Clauses))
8887 return StmtError();
8888
8889 setFunctionHasBranchProtectedScope();
8890 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8891 Clauses, AStmt, B);
8892}
8893
8894StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
8895 Stmt *AStmt,
8896 SourceLocation StartLoc,
8897 SourceLocation EndLoc) {
8898 if (!AStmt)
8899 return StmtError();
8900
8901 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8901, __PRETTY_FUNCTION__))
;
8902 auto BaseStmt = AStmt;
8903 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8904 BaseStmt = CS->getCapturedStmt();
8905 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8906 auto S = C->children();
8907 if (S.begin() == S.end())
8908 return StmtError();
8909 // All associated statements must be '#pragma omp section' except for
8910 // the first one.
8911 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8912 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8913 if (SectionStmt)
8914 Diag(SectionStmt->getBeginLoc(),
8915 diag::err_omp_sections_substmt_not_section);
8916 return StmtError();
8917 }
8918 cast<OMPSectionDirective>(SectionStmt)
8919 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8920 }
8921 } else {
8922 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
8923 return StmtError();
8924 }
8925
8926 setFunctionHasBranchProtectedScope();
8927
8928 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8929 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(),
8930 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8931}
8932
8933StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
8934 SourceLocation StartLoc,
8935 SourceLocation EndLoc) {
8936 if (!AStmt)
8937 return StmtError();
8938
8939 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8939, __PRETTY_FUNCTION__))
;
8940
8941 setFunctionHasBranchProtectedScope();
8942 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8943
8944 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
8945 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8946}
8947
8948StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
8949 Stmt *AStmt,
8950 SourceLocation StartLoc,
8951 SourceLocation EndLoc) {
8952 if (!AStmt)
8953 return StmtError();
8954
8955 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8955, __PRETTY_FUNCTION__))
;
8956
8957 setFunctionHasBranchProtectedScope();
8958
8959 // OpenMP [2.7.3, single Construct, Restrictions]
8960 // The copyprivate clause must not be used with the nowait clause.
8961 const OMPClause *Nowait = nullptr;
8962 const OMPClause *Copyprivate = nullptr;
8963 for (const OMPClause *Clause : Clauses) {
8964 if (Clause->getClauseKind() == OMPC_nowait)
8965 Nowait = Clause;
8966 else if (Clause->getClauseKind() == OMPC_copyprivate)
8967 Copyprivate = Clause;
8968 if (Copyprivate && Nowait) {
8969 Diag(Copyprivate->getBeginLoc(),
8970 diag::err_omp_single_copyprivate_with_nowait);
8971 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
8972 return StmtError();
8973 }
8974 }
8975
8976 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8977}
8978
8979StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
8980 SourceLocation StartLoc,
8981 SourceLocation EndLoc) {
8982 if (!AStmt)
8983 return StmtError();
8984
8985 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8985, __PRETTY_FUNCTION__))
;
8986
8987 setFunctionHasBranchProtectedScope();
8988
8989 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
8990}
8991
8992StmtResult Sema::ActOnOpenMPCriticalDirective(
8993 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
8994 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
8995 if (!AStmt)
8996 return StmtError();
8997
8998 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 8998, __PRETTY_FUNCTION__))
;
8999
9000 bool ErrorFound = false;
9001 llvm::APSInt Hint;
9002 SourceLocation HintLoc;
9003 bool DependentHint = false;
9004 for (const OMPClause *C : Clauses) {
9005 if (C->getClauseKind() == OMPC_hint) {
9006 if (!DirName.getName()) {
9007 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9008 ErrorFound = true;
9009 }
9010 Expr *E = cast<OMPHintClause>(C)->getHint();
9011 if (E->isTypeDependent() || E->isValueDependent() ||
9012 E->isInstantiationDependent()) {
9013 DependentHint = true;
9014 } else {
9015 Hint = E->EvaluateKnownConstInt(Context);
9016 HintLoc = C->getBeginLoc();
9017 }
9018 }
9019 }
9020 if (ErrorFound)
9021 return StmtError();
9022 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
9023 if (Pair.first && DirName.getName() && !DependentHint) {
9024 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9025 Diag(StartLoc, diag::err_omp_critical_with_hint);
9026 if (HintLoc.isValid())
9027 Diag(HintLoc, diag::note_omp_critical_hint_here)
9028 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9029 else
9030 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9031 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9032 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9033 << 1
9034 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9035 /*Radix=*/10, /*Signed=*/false);
9036 } else {
9037 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9038 }
9039 }
9040 }
9041
9042 setFunctionHasBranchProtectedScope();
9043
9044 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9045 Clauses, AStmt);
9046 if (!Pair.first && DirName.getName() && !DependentHint)
9047 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
9048 return Dir;
9049}
9050
9051StmtResult Sema::ActOnOpenMPParallelForDirective(
9052 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9053 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9054 if (!AStmt)
9055 return StmtError();
9056
9057 auto *CS = cast<CapturedStmt>(AStmt);
9058 // 1.2.2 OpenMP Language Terminology
9059 // Structured block - An executable statement with a single entry at the
9060 // top and a single exit at the bottom.
9061 // The point of exit cannot be a branch out of the structured block.
9062 // longjmp() and throw() must not violate the entry/exit criteria.
9063 CS->getCapturedDecl()->setNothrow();
9064
9065 OMPLoopDirective::HelperExprs B;
9066 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9067 // define the nested loops number.
9068 unsigned NestedLoopCount =
9069 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9070 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9071 VarsWithImplicitDSA, B);
9072 if (NestedLoopCount == 0)
9073 return StmtError();
9074
9075 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9076, __PRETTY_FUNCTION__))
9076 "omp parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp parallel for loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9076, __PRETTY_FUNCTION__))
;
9077
9078 if (!CurContext->isDependentContext()) {
9079 // Finalize the clauses that need pre-built expressions for CodeGen.
9080 for (OMPClause *C : Clauses) {
9081 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9082 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9083 B.NumIterations, *this, CurScope,
9084 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9085 return StmtError();
9086 }
9087 }
9088
9089 setFunctionHasBranchProtectedScope();
9090 return OMPParallelForDirective::Create(
9091 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9092 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9093}
9094
9095StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9096 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9097 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9098 if (!AStmt)
9099 return StmtError();
9100
9101 auto *CS = cast<CapturedStmt>(AStmt);
9102 // 1.2.2 OpenMP Language Terminology
9103 // Structured block - An executable statement with a single entry at the
9104 // top and a single exit at the bottom.
9105 // The point of exit cannot be a branch out of the structured block.
9106 // longjmp() and throw() must not violate the entry/exit criteria.
9107 CS->getCapturedDecl()->setNothrow();
9108
9109 OMPLoopDirective::HelperExprs B;
9110 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9111 // define the nested loops number.
9112 unsigned NestedLoopCount =
9113 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9114 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9115 VarsWithImplicitDSA, B);
9116 if (NestedLoopCount == 0)
9117 return StmtError();
9118
9119 if (!CurContext->isDependentContext()) {
9120 // Finalize the clauses that need pre-built expressions for CodeGen.
9121 for (OMPClause *C : Clauses) {
9122 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9123 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9124 B.NumIterations, *this, CurScope,
9125 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9126 return StmtError();
9127 }
9128 }
9129
9130 if (checkSimdlenSafelenSpecified(*this, Clauses))
9131 return StmtError();
9132
9133 setFunctionHasBranchProtectedScope();
9134 return OMPParallelForSimdDirective::Create(
9135 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9136}
9137
9138StmtResult
9139Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9140 Stmt *AStmt, SourceLocation StartLoc,
9141 SourceLocation EndLoc) {
9142 if (!AStmt)
9143 return StmtError();
9144
9145 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9145, __PRETTY_FUNCTION__))
;
9146 auto *CS = cast<CapturedStmt>(AStmt);
9147 // 1.2.2 OpenMP Language Terminology
9148 // Structured block - An executable statement with a single entry at the
9149 // top and a single exit at the bottom.
9150 // The point of exit cannot be a branch out of the structured block.
9151 // longjmp() and throw() must not violate the entry/exit criteria.
9152 CS->getCapturedDecl()->setNothrow();
9153
9154 setFunctionHasBranchProtectedScope();
9155
9156 return OMPParallelMasterDirective::Create(
9157 Context, StartLoc, EndLoc, Clauses, AStmt,
9158 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9159}
9160
9161StmtResult
9162Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9163 Stmt *AStmt, SourceLocation StartLoc,
9164 SourceLocation EndLoc) {
9165 if (!AStmt)
9166 return StmtError();
9167
9168 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9168, __PRETTY_FUNCTION__))
;
9169 auto BaseStmt = AStmt;
9170 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9171 BaseStmt = CS->getCapturedStmt();
9172 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9173 auto S = C->children();
9174 if (S.begin() == S.end())
9175 return StmtError();
9176 // All associated statements must be '#pragma omp section' except for
9177 // the first one.
9178 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9179 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9180 if (SectionStmt)
9181 Diag(SectionStmt->getBeginLoc(),
9182 diag::err_omp_parallel_sections_substmt_not_section);
9183 return StmtError();
9184 }
9185 cast<OMPSectionDirective>(SectionStmt)
9186 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9187 }
9188 } else {
9189 Diag(AStmt->getBeginLoc(),
9190 diag::err_omp_parallel_sections_not_compound_stmt);
9191 return StmtError();
9192 }
9193
9194 setFunctionHasBranchProtectedScope();
9195
9196 return OMPParallelSectionsDirective::Create(
9197 Context, StartLoc, EndLoc, Clauses, AStmt,
9198 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9199}
9200
9201/// detach and mergeable clauses are mutially exclusive, check for it.
9202static bool checkDetachMergeableClauses(Sema &S,
9203 ArrayRef<OMPClause *> Clauses) {
9204 const OMPClause *PrevClause = nullptr;
9205 bool ErrorFound = false;
9206 for (const OMPClause *C : Clauses) {
9207 if (C->getClauseKind() == OMPC_detach ||
9208 C->getClauseKind() == OMPC_mergeable) {
9209 if (!PrevClause) {
9210 PrevClause = C;
9211 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9212 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9213 << getOpenMPClauseName(C->getClauseKind())
9214 << getOpenMPClauseName(PrevClause->getClauseKind());
9215 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9216 << getOpenMPClauseName(PrevClause->getClauseKind());
9217 ErrorFound = true;
9218 }
9219 }
9220 }
9221 return ErrorFound;
9222}
9223
9224StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9225 Stmt *AStmt, SourceLocation StartLoc,
9226 SourceLocation EndLoc) {
9227 if (!AStmt)
9228 return StmtError();
9229
9230 // OpenMP 5.0, 2.10.1 task Construct
9231 // If a detach clause appears on the directive, then a mergeable clause cannot
9232 // appear on the same directive.
9233 if (checkDetachMergeableClauses(*this, Clauses))
9234 return StmtError();
9235
9236 auto *CS = cast<CapturedStmt>(AStmt);
9237 // 1.2.2 OpenMP Language Terminology
9238 // Structured block - An executable statement with a single entry at the
9239 // top and a single exit at the bottom.
9240 // The point of exit cannot be a branch out of the structured block.
9241 // longjmp() and throw() must not violate the entry/exit criteria.
9242 CS->getCapturedDecl()->setNothrow();
9243
9244 setFunctionHasBranchProtectedScope();
9245
9246 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9247 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9248}
9249
9250StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9251 SourceLocation EndLoc) {
9252 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9253}
9254
9255StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9256 SourceLocation EndLoc) {
9257 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9258}
9259
9260StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9261 SourceLocation EndLoc) {
9262 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9263}
9264
9265StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9266 Stmt *AStmt,
9267 SourceLocation StartLoc,
9268 SourceLocation EndLoc) {
9269 if (!AStmt)
9270 return StmtError();
9271
9272 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9272, __PRETTY_FUNCTION__))
;
9273
9274 setFunctionHasBranchProtectedScope();
9275
9276 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9277 AStmt,
9278 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
9279}
9280
9281StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9282 SourceLocation StartLoc,
9283 SourceLocation EndLoc) {
9284 OMPFlushClause *FC = nullptr;
9285 OMPClause *OrderClause = nullptr;
9286 for (OMPClause *C : Clauses) {
9287 if (C->getClauseKind() == OMPC_flush)
9288 FC = cast<OMPFlushClause>(C);
9289 else
9290 OrderClause = C;
9291 }
9292 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9293 SourceLocation MemOrderLoc;
9294 for (const OMPClause *C : Clauses) {
9295 if (C->getClauseKind() == OMPC_acq_rel ||
9296 C->getClauseKind() == OMPC_acquire ||
9297 C->getClauseKind() == OMPC_release) {
9298 if (MemOrderKind != OMPC_unknown) {
9299 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9300 << getOpenMPDirectiveName(OMPD_flush) << 1
9301 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9302 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9303 << getOpenMPClauseName(MemOrderKind);
9304 } else {
9305 MemOrderKind = C->getClauseKind();
9306 MemOrderLoc = C->getBeginLoc();
9307 }
9308 }
9309 }
9310 if (FC && OrderClause) {
9311 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9312 << getOpenMPClauseName(OrderClause->getClauseKind());
9313 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9314 << getOpenMPClauseName(OrderClause->getClauseKind());
9315 return StmtError();
9316 }
9317 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9318}
9319
9320StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9321 SourceLocation StartLoc,
9322 SourceLocation EndLoc) {
9323 if (Clauses.empty()) {
9324 Diag(StartLoc, diag::err_omp_depobj_expected);
9325 return StmtError();
9326 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9327 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9328 return StmtError();
9329 }
9330 // Only depobj expression and another single clause is allowed.
9331 if (Clauses.size() > 2) {
9332 Diag(Clauses[2]->getBeginLoc(),
9333 diag::err_omp_depobj_single_clause_expected);
9334 return StmtError();
9335 } else if (Clauses.size() < 1) {
9336 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9337 return StmtError();
9338 }
9339 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9340}
9341
9342StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9343 SourceLocation StartLoc,
9344 SourceLocation EndLoc) {
9345 // Check that exactly one clause is specified.
9346 if (Clauses.size() != 1) {
9347 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9348 diag::err_omp_scan_single_clause_expected);
9349 return StmtError();
9350 }
9351 // Check that scan directive is used in the scopeof the OpenMP loop body.
9352 if (Scope *S = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope()) {
9353 Scope *ParentS = S->getParent();
9354 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9355 !ParentS->getBreakParent()->isOpenMPLoopScope())
9356 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9357 << getOpenMPDirectiveName(OMPD_scan) << 5);
9358 }
9359 // Check that only one instance of scan directives is used in the same outer
9360 // region.
9361 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasScanDirective()) {
9362 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9363 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentScanDirectiveLoc(),
9364 diag::note_omp_previous_directive)
9365 << "scan";
9366 return StmtError();
9367 }
9368 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasScanDirective(StartLoc);
9369 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9370}
9371
9372StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9373 Stmt *AStmt,
9374 SourceLocation StartLoc,
9375 SourceLocation EndLoc) {
9376 const OMPClause *DependFound = nullptr;
9377 const OMPClause *DependSourceClause = nullptr;
9378 const OMPClause *DependSinkClause = nullptr;
9379 bool ErrorFound = false;
9380 const OMPThreadsClause *TC = nullptr;
9381 const OMPSIMDClause *SC = nullptr;
9382 for (const OMPClause *C : Clauses) {
9383 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9384 DependFound = C;
9385 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9386 if (DependSourceClause) {
9387 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9388 << getOpenMPDirectiveName(OMPD_ordered)
9389 << getOpenMPClauseName(OMPC_depend) << 2;
9390 ErrorFound = true;
9391 } else {
9392 DependSourceClause = C;
9393 }
9394 if (DependSinkClause) {
9395 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9396 << 0;
9397 ErrorFound = true;
9398 }
9399 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9400 if (DependSourceClause) {
9401 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9402 << 1;
9403 ErrorFound = true;
9404 }
9405 DependSinkClause = C;
9406 }
9407 } else if (C->getClauseKind() == OMPC_threads) {
9408 TC = cast<OMPThreadsClause>(C);
9409 } else if (C->getClauseKind() == OMPC_simd) {
9410 SC = cast<OMPSIMDClause>(C);
9411 }
9412 }
9413 if (!ErrorFound && !SC &&
9414 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
9415 // OpenMP [2.8.1,simd Construct, Restrictions]
9416 // An ordered construct with the simd clause is the only OpenMP construct
9417 // that can appear in the simd region.
9418 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9419 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9420 ErrorFound = true;
9421 } else if (DependFound && (TC || SC)) {
9422 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9423 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9424 ErrorFound = true;
9425 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9426 Diag(DependFound->getBeginLoc(),
9427 diag::err_omp_ordered_directive_without_param);
9428 ErrorFound = true;
9429 } else if (TC || Clauses.empty()) {
9430 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
9431 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9432 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9433 << (TC != nullptr);
9434 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9435 ErrorFound = true;
9436 }
9437 }
9438 if ((!AStmt && !DependFound) || ErrorFound)
9439 return StmtError();
9440
9441 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9442 // During execution of an iteration of a worksharing-loop or a loop nest
9443 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9444 // must not execute more than one ordered region corresponding to an ordered
9445 // construct without a depend clause.
9446 if (!DependFound) {
9447 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->doesParentHasOrderedDirective()) {
9448 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9449 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedDirectiveLoc(),
9450 diag::note_omp_previous_directive)
9451 << "ordered";
9452 return StmtError();
9453 }
9454 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentHasOrderedDirective(StartLoc);
9455 }
9456
9457 if (AStmt) {
9458 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 9458, __PRETTY_FUNCTION__))
;
9459
9460 setFunctionHasBranchProtectedScope();
9461 }
9462
9463 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9464}
9465
9466namespace {
9467/// Helper class for checking expression in 'omp atomic [update]'
9468/// construct.
9469class OpenMPAtomicUpdateChecker {
9470 /// Error results for atomic update expressions.
9471 enum ExprAnalysisErrorCode {
9472 /// A statement is not an expression statement.
9473 NotAnExpression,
9474 /// Expression is not builtin binary or unary operation.
9475 NotABinaryOrUnaryExpression,
9476 /// Unary operation is not post-/pre- increment/decrement operation.
9477 NotAnUnaryIncDecExpression,
9478 /// An expression is not of scalar type.
9479 NotAScalarType,
9480 /// A binary operation is not an assignment operation.
9481 NotAnAssignmentOp,
9482 /// RHS part of the binary operation is not a binary expression.
9483 NotABinaryExpression,
9484 /// RHS part is not additive/multiplicative/shift/biwise binary
9485 /// expression.
9486 NotABinaryOperator,
9487 /// RHS binary operation does not have reference to the updated LHS
9488 /// part.
9489 NotAnUpdateExpression,
9490 /// No errors is found.
9491 NoError
9492 };
9493 /// Reference to Sema.
9494 Sema &SemaRef;
9495 /// A location for note diagnostics (when error is found).
9496 SourceLocation NoteLoc;
9497 /// 'x' lvalue part of the source atomic expression.
9498 Expr *X;
9499 /// 'expr' rvalue part of the source atomic expression.
9500 Expr *E;
9501 /// Helper expression of the form
9502 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9503 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9504 Expr *UpdateExpr;
9505 /// Is 'x' a LHS in a RHS part of full update expression. It is
9506 /// important for non-associative operations.
9507 bool IsXLHSInRHSPart;
9508 BinaryOperatorKind Op;
9509 SourceLocation OpLoc;
9510 /// true if the source expression is a postfix unary operation, false
9511 /// if it is a prefix unary operation.
9512 bool IsPostfixUpdate;
9513
9514public:
9515 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9516 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9517 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9518 /// Check specified statement that it is suitable for 'atomic update'
9519 /// constructs and extract 'x', 'expr' and Operation from the original
9520 /// expression. If DiagId and NoteId == 0, then only check is performed
9521 /// without error notification.
9522 /// \param DiagId Diagnostic which should be emitted if error is found.
9523 /// \param NoteId Diagnostic note for the main error message.
9524 /// \return true if statement is not an update expression, false otherwise.
9525 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9526 /// Return the 'x' lvalue part of the source atomic expression.
9527 Expr *getX() const { return X; }
9528 /// Return the 'expr' rvalue part of the source atomic expression.
9529 Expr *getExpr() const { return E; }
9530 /// Return the update expression used in calculation of the updated
9531 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9532 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9533 Expr *getUpdateExpr() const { return UpdateExpr; }
9534 /// Return true if 'x' is LHS in RHS part of full update expression,
9535 /// false otherwise.
9536 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9537
9538 /// true if the source expression is a postfix unary operation, false
9539 /// if it is a prefix unary operation.
9540 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9541
9542private:
9543 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9544 unsigned NoteId = 0);
9545};
9546} // namespace
9547
9548bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9549 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9550 ExprAnalysisErrorCode ErrorFound = NoError;
9551 SourceLocation ErrorLoc, NoteLoc;
9552 SourceRange ErrorRange, NoteRange;
9553 // Allowed constructs are:
9554 // x = x binop expr;
9555 // x = expr binop x;
9556 if (AtomicBinOp->getOpcode() == BO_Assign) {
9557 X = AtomicBinOp->getLHS();
9558 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9559 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9560 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9561 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9562 AtomicInnerBinOp->isBitwiseOp()) {
9563 Op = AtomicInnerBinOp->getOpcode();
9564 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9565 Expr *LHS = AtomicInnerBinOp->getLHS();
9566 Expr *RHS = AtomicInnerBinOp->getRHS();
9567 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9568 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9569 /*Canonical=*/true);
9570 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9571 /*Canonical=*/true);
9572 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9573 /*Canonical=*/true);
9574 if (XId == LHSId) {
9575 E = RHS;
9576 IsXLHSInRHSPart = true;
9577 } else if (XId == RHSId) {
9578 E = LHS;
9579 IsXLHSInRHSPart = false;
9580 } else {
9581 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9582 ErrorRange = AtomicInnerBinOp->getSourceRange();
9583 NoteLoc = X->getExprLoc();
9584 NoteRange = X->getSourceRange();
9585 ErrorFound = NotAnUpdateExpression;
9586 }
9587 } else {
9588 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9589 ErrorRange = AtomicInnerBinOp->getSourceRange();
9590 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9591 NoteRange = SourceRange(NoteLoc, NoteLoc);
9592 ErrorFound = NotABinaryOperator;
9593 }
9594 } else {
9595 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9596 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9597 ErrorFound = NotABinaryExpression;
9598 }
9599 } else {
9600 ErrorLoc = AtomicBinOp->getExprLoc();
9601 ErrorRange = AtomicBinOp->getSourceRange();
9602 NoteLoc = AtomicBinOp->getOperatorLoc();
9603 NoteRange = SourceRange(NoteLoc, NoteLoc);
9604 ErrorFound = NotAnAssignmentOp;
9605 }
9606 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9607 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9608 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9609 return true;
9610 }
9611 if (SemaRef.CurContext->isDependentContext())
9612 E = X = UpdateExpr = nullptr;
9613 return ErrorFound != NoError;
9614}
9615
9616bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9617 unsigned NoteId) {
9618 ExprAnalysisErrorCode ErrorFound = NoError;
9619 SourceLocation ErrorLoc, NoteLoc;
9620 SourceRange ErrorRange, NoteRange;
9621 // Allowed constructs are:
9622 // x++;
9623 // x--;
9624 // ++x;
9625 // --x;
9626 // x binop= expr;
9627 // x = x binop expr;
9628 // x = expr binop x;
9629 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9630 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9631 if (AtomicBody->getType()->isScalarType() ||
9632 AtomicBody->isInstantiationDependent()) {
9633 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9634 AtomicBody->IgnoreParenImpCasts())) {
9635 // Check for Compound Assignment Operation
9636 Op = BinaryOperator::getOpForCompoundAssignment(
9637 AtomicCompAssignOp->getOpcode());
9638 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9639 E = AtomicCompAssignOp->getRHS();
9640 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9641 IsXLHSInRHSPart = true;
9642 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9643 AtomicBody->IgnoreParenImpCasts())) {
9644 // Check for Binary Operation
9645 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9646 return true;
9647 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9648 AtomicBody->IgnoreParenImpCasts())) {
9649 // Check for Unary Operation
9650 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9651 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9652 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9653 OpLoc = AtomicUnaryOp->getOperatorLoc();
9654 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9655 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9656 IsXLHSInRHSPart = true;
9657 } else {
9658 ErrorFound = NotAnUnaryIncDecExpression;
9659 ErrorLoc = AtomicUnaryOp->getExprLoc();
9660 ErrorRange = AtomicUnaryOp->getSourceRange();
9661 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9662 NoteRange = SourceRange(NoteLoc, NoteLoc);
9663 }
9664 } else if (!AtomicBody->isInstantiationDependent()) {
9665 ErrorFound = NotABinaryOrUnaryExpression;
9666 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9667 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9668 }
9669 } else {
9670 ErrorFound = NotAScalarType;
9671 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9672 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9673 }
9674 } else {
9675 ErrorFound = NotAnExpression;
9676 NoteLoc = ErrorLoc = S->getBeginLoc();
9677 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9678 }
9679 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9680 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9681 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9682 return true;
9683 }
9684 if (SemaRef.CurContext->isDependentContext())
9685 E = X = UpdateExpr = nullptr;
9686 if (ErrorFound == NoError && E && X) {
9687 // Build an update expression of form 'OpaqueValueExpr(x) binop
9688 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9689 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9690 auto *OVEX = new (SemaRef.getASTContext())
9691 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9692 auto *OVEExpr = new (SemaRef.getASTContext())
9693 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9694 ExprResult Update =
9695 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9696 IsXLHSInRHSPart ? OVEExpr : OVEX);
9697 if (Update.isInvalid())
9698 return true;
9699 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9700 Sema::AA_Casting);
9701 if (Update.isInvalid())
9702 return true;
9703 UpdateExpr = Update.get();
9704 }
9705 return ErrorFound != NoError;
9706}
9707
9708StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9709 Stmt *AStmt,
9710 SourceLocation StartLoc,
9711 SourceLocation EndLoc) {
9712 // Register location of the first atomic directive.
9713 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
9714 if (!AStmt)
9715 return StmtError();
9716
9717 auto *CS = cast<CapturedStmt>(AStmt);
9718 // 1.2.2 OpenMP Language Terminology
9719 // Structured block - An executable statement with a single entry at the
9720 // top and a single exit at the bottom.
9721 // The point of exit cannot be a branch out of the structured block.
9722 // longjmp() and throw() must not violate the entry/exit criteria.
9723 OpenMPClauseKind AtomicKind = OMPC_unknown;
9724 SourceLocation AtomicKindLoc;
9725 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9726 SourceLocation MemOrderLoc;
9727 for (const OMPClause *C : Clauses) {
9728 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9729 C->getClauseKind() == OMPC_update ||
9730 C->getClauseKind() == OMPC_capture) {
9731 if (AtomicKind != OMPC_unknown) {
9732 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9733 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9734 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9735 << getOpenMPClauseName(AtomicKind);
9736 } else {
9737 AtomicKind = C->getClauseKind();
9738 AtomicKindLoc = C->getBeginLoc();
9739 }
9740 }
9741 if (C->getClauseKind() == OMPC_seq_cst ||
9742 C->getClauseKind() == OMPC_acq_rel ||
9743 C->getClauseKind() == OMPC_acquire ||
9744 C->getClauseKind() == OMPC_release ||
9745 C->getClauseKind() == OMPC_relaxed) {
9746 if (MemOrderKind != OMPC_unknown) {
9747 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9748 << getOpenMPDirectiveName(OMPD_atomic) << 0
9749 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9750 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9751 << getOpenMPClauseName(MemOrderKind);
9752 } else {
9753 MemOrderKind = C->getClauseKind();
9754 MemOrderLoc = C->getBeginLoc();
9755 }
9756 }
9757 }
9758 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9759 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9760 // release.
9761 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9762 // acquire.
9763 // If atomic-clause is update or not present then memory-order-clause must not
9764 // be acq_rel or acquire.
9765 if ((AtomicKind == OMPC_read &&
9766 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9767 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9768 AtomicKind == OMPC_unknown) &&
9769 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9770 SourceLocation Loc = AtomicKindLoc;
9771 if (AtomicKind == OMPC_unknown)
9772 Loc = StartLoc;
9773 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9774 << getOpenMPClauseName(AtomicKind)
9775 << (AtomicKind == OMPC_unknown ? 1 : 0)
9776 << getOpenMPClauseName(MemOrderKind);
9777 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9778 << getOpenMPClauseName(MemOrderKind);
9779 }
9780
9781 Stmt *Body = CS->getCapturedStmt();
9782 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9783 Body = EWC->getSubExpr();
9784
9785 Expr *X = nullptr;
9786 Expr *V = nullptr;
9787 Expr *E = nullptr;
9788 Expr *UE = nullptr;
9789 bool IsXLHSInRHSPart = false;
9790 bool IsPostfixUpdate = false;
9791 // OpenMP [2.12.6, atomic Construct]
9792 // In the next expressions:
9793 // * x and v (as applicable) are both l-value expressions with scalar type.
9794 // * During the execution of an atomic region, multiple syntactic
9795 // occurrences of x must designate the same storage location.
9796 // * Neither of v and expr (as applicable) may access the storage location
9797 // designated by x.
9798 // * Neither of x and expr (as applicable) may access the storage location
9799 // designated by v.
9800 // * expr is an expression with scalar type.
9801 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9802 // * binop, binop=, ++, and -- are not overloaded operators.
9803 // * The expression x binop expr must be numerically equivalent to x binop
9804 // (expr). This requirement is satisfied if the operators in expr have
9805 // precedence greater than binop, or by using parentheses around expr or
9806 // subexpressions of expr.
9807 // * The expression expr binop x must be numerically equivalent to (expr)
9808 // binop x. This requirement is satisfied if the operators in expr have
9809 // precedence equal to or greater than binop, or by using parentheses around
9810 // expr or subexpressions of expr.
9811 // * For forms that allow multiple occurrences of x, the number of times
9812 // that x is evaluated is unspecified.
9813 if (AtomicKind == OMPC_read) {
9814 enum {
9815 NotAnExpression,
9816 NotAnAssignmentOp,
9817 NotAScalarType,
9818 NotAnLValue,
9819 NoError
9820 } ErrorFound = NoError;
9821 SourceLocation ErrorLoc, NoteLoc;
9822 SourceRange ErrorRange, NoteRange;
9823 // If clause is read:
9824 // v = x;
9825 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9826 const auto *AtomicBinOp =
9827 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9828 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9829 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9830 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9831 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9832 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9833 if (!X->isLValue() || !V->isLValue()) {
9834 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9835 ErrorFound = NotAnLValue;
9836 ErrorLoc = AtomicBinOp->getExprLoc();
9837 ErrorRange = AtomicBinOp->getSourceRange();
9838 NoteLoc = NotLValueExpr->getExprLoc();
9839 NoteRange = NotLValueExpr->getSourceRange();
9840 }
9841 } else if (!X->isInstantiationDependent() ||
9842 !V->isInstantiationDependent()) {
9843 const Expr *NotScalarExpr =
9844 (X->isInstantiationDependent() || X->getType()->isScalarType())
9845 ? V
9846 : X;
9847 ErrorFound = NotAScalarType;
9848 ErrorLoc = AtomicBinOp->getExprLoc();
9849 ErrorRange = AtomicBinOp->getSourceRange();
9850 NoteLoc = NotScalarExpr->getExprLoc();
9851 NoteRange = NotScalarExpr->getSourceRange();
9852 }
9853 } else if (!AtomicBody->isInstantiationDependent()) {
9854 ErrorFound = NotAnAssignmentOp;
9855 ErrorLoc = AtomicBody->getExprLoc();
9856 ErrorRange = AtomicBody->getSourceRange();
9857 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9858 : AtomicBody->getExprLoc();
9859 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9860 : AtomicBody->getSourceRange();
9861 }
9862 } else {
9863 ErrorFound = NotAnExpression;
9864 NoteLoc = ErrorLoc = Body->getBeginLoc();
9865 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9866 }
9867 if (ErrorFound != NoError) {
9868 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9869 << ErrorRange;
9870 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9871 << NoteRange;
9872 return StmtError();
9873 }
9874 if (CurContext->isDependentContext())
9875 V = X = nullptr;
9876 } else if (AtomicKind == OMPC_write) {
9877 enum {
9878 NotAnExpression,
9879 NotAnAssignmentOp,
9880 NotAScalarType,
9881 NotAnLValue,
9882 NoError
9883 } ErrorFound = NoError;
9884 SourceLocation ErrorLoc, NoteLoc;
9885 SourceRange ErrorRange, NoteRange;
9886 // If clause is write:
9887 // x = expr;
9888 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9889 const auto *AtomicBinOp =
9890 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9891 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9892 X = AtomicBinOp->getLHS();
9893 E = AtomicBinOp->getRHS();
9894 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9895 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
9896 if (!X->isLValue()) {
9897 ErrorFound = NotAnLValue;
9898 ErrorLoc = AtomicBinOp->getExprLoc();
9899 ErrorRange = AtomicBinOp->getSourceRange();
9900 NoteLoc = X->getExprLoc();
9901 NoteRange = X->getSourceRange();
9902 }
9903 } else if (!X->isInstantiationDependent() ||
9904 !E->isInstantiationDependent()) {
9905 const Expr *NotScalarExpr =
9906 (X->isInstantiationDependent() || X->getType()->isScalarType())
9907 ? E
9908 : X;
9909 ErrorFound = NotAScalarType;
9910 ErrorLoc = AtomicBinOp->getExprLoc();
9911 ErrorRange = AtomicBinOp->getSourceRange();
9912 NoteLoc = NotScalarExpr->getExprLoc();
9913 NoteRange = NotScalarExpr->getSourceRange();
9914 }
9915 } else if (!AtomicBody->isInstantiationDependent()) {
9916 ErrorFound = NotAnAssignmentOp;
9917 ErrorLoc = AtomicBody->getExprLoc();
9918 ErrorRange = AtomicBody->getSourceRange();
9919 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9920 : AtomicBody->getExprLoc();
9921 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9922 : AtomicBody->getSourceRange();
9923 }
9924 } else {
9925 ErrorFound = NotAnExpression;
9926 NoteLoc = ErrorLoc = Body->getBeginLoc();
9927 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9928 }
9929 if (ErrorFound != NoError) {
9930 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
9931 << ErrorRange;
9932 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9933 << NoteRange;
9934 return StmtError();
9935 }
9936 if (CurContext->isDependentContext())
9937 E = X = nullptr;
9938 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
9939 // If clause is update:
9940 // x++;
9941 // x--;
9942 // ++x;
9943 // --x;
9944 // x binop= expr;
9945 // x = x binop expr;
9946 // x = expr binop x;
9947 OpenMPAtomicUpdateChecker Checker(*this);
9948 if (Checker.checkStatement(
9949 Body, (AtomicKind == OMPC_update)
9950 ? diag::err_omp_atomic_update_not_expression_statement
9951 : diag::err_omp_atomic_not_expression_statement,
9952 diag::note_omp_atomic_update))
9953 return StmtError();
9954 if (!CurContext->isDependentContext()) {
9955 E = Checker.getExpr();
9956 X = Checker.getX();
9957 UE = Checker.getUpdateExpr();
9958 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9959 }
9960 } else if (AtomicKind == OMPC_capture) {
9961 enum {
9962 NotAnAssignmentOp,
9963 NotACompoundStatement,
9964 NotTwoSubstatements,
9965 NotASpecificExpression,
9966 NoError
9967 } ErrorFound = NoError;
9968 SourceLocation ErrorLoc, NoteLoc;
9969 SourceRange ErrorRange, NoteRange;
9970 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9971 // If clause is a capture:
9972 // v = x++;
9973 // v = x--;
9974 // v = ++x;
9975 // v = --x;
9976 // v = x binop= expr;
9977 // v = x = x binop expr;
9978 // v = x = expr binop x;
9979 const auto *AtomicBinOp =
9980 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9981 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9982 V = AtomicBinOp->getLHS();
9983 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9984 OpenMPAtomicUpdateChecker Checker(*this);
9985 if (Checker.checkStatement(
9986 Body, diag::err_omp_atomic_capture_not_expression_statement,
9987 diag::note_omp_atomic_update))
9988 return StmtError();
9989 E = Checker.getExpr();
9990 X = Checker.getX();
9991 UE = Checker.getUpdateExpr();
9992 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9993 IsPostfixUpdate = Checker.isPostfixUpdate();
9994 } else if (!AtomicBody->isInstantiationDependent()) {
9995 ErrorLoc = AtomicBody->getExprLoc();
9996 ErrorRange = AtomicBody->getSourceRange();
9997 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9998 : AtomicBody->getExprLoc();
9999 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10000 : AtomicBody->getSourceRange();
10001 ErrorFound = NotAnAssignmentOp;
10002 }
10003 if (ErrorFound != NoError) {
10004 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10005 << ErrorRange;
10006 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10007 return StmtError();
10008 }
10009 if (CurContext->isDependentContext())
10010 UE = V = E = X = nullptr;
10011 } else {
10012 // If clause is a capture:
10013 // { v = x; x = expr; }
10014 // { v = x; x++; }
10015 // { v = x; x--; }
10016 // { v = x; ++x; }
10017 // { v = x; --x; }
10018 // { v = x; x binop= expr; }
10019 // { v = x; x = x binop expr; }
10020 // { v = x; x = expr binop x; }
10021 // { x++; v = x; }
10022 // { x--; v = x; }
10023 // { ++x; v = x; }
10024 // { --x; v = x; }
10025 // { x binop= expr; v = x; }
10026 // { x = x binop expr; v = x; }
10027 // { x = expr binop x; v = x; }
10028 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10029 // Check that this is { expr1; expr2; }
10030 if (CS->size() == 2) {
10031 Stmt *First = CS->body_front();
10032 Stmt *Second = CS->body_back();
10033 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10034 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10035 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10036 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10037 // Need to find what subexpression is 'v' and what is 'x'.
10038 OpenMPAtomicUpdateChecker Checker(*this);
10039 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10040 BinaryOperator *BinOp = nullptr;
10041 if (IsUpdateExprFound) {
10042 BinOp = dyn_cast<BinaryOperator>(First);
10043 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10044 }
10045 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10046 // { v = x; x++; }
10047 // { v = x; x--; }
10048 // { v = x; ++x; }
10049 // { v = x; --x; }
10050 // { v = x; x binop= expr; }
10051 // { v = x; x = x binop expr; }
10052 // { v = x; x = expr binop x; }
10053 // Check that the first expression has form v = x.
10054 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10055 llvm::FoldingSetNodeID XId, PossibleXId;
10056 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10057 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10058 IsUpdateExprFound = XId == PossibleXId;
10059 if (IsUpdateExprFound) {
10060 V = BinOp->getLHS();
10061 X = Checker.getX();
10062 E = Checker.getExpr();
10063 UE = Checker.getUpdateExpr();
10064 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10065 IsPostfixUpdate = true;
10066 }
10067 }
10068 if (!IsUpdateExprFound) {
10069 IsUpdateExprFound = !Checker.checkStatement(First);
10070 BinOp = nullptr;
10071 if (IsUpdateExprFound) {
10072 BinOp = dyn_cast<BinaryOperator>(Second);
10073 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10074 }
10075 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10076 // { x++; v = x; }
10077 // { x--; v = x; }
10078 // { ++x; v = x; }
10079 // { --x; v = x; }
10080 // { x binop= expr; v = x; }
10081 // { x = x binop expr; v = x; }
10082 // { x = expr binop x; v = x; }
10083 // Check that the second expression has form v = x.
10084 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10085 llvm::FoldingSetNodeID XId, PossibleXId;
10086 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10087 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10088 IsUpdateExprFound = XId == PossibleXId;
10089 if (IsUpdateExprFound) {
10090 V = BinOp->getLHS();
10091 X = Checker.getX();
10092 E = Checker.getExpr();
10093 UE = Checker.getUpdateExpr();
10094 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10095 IsPostfixUpdate = false;
10096 }
10097 }
10098 }
10099 if (!IsUpdateExprFound) {
10100 // { v = x; x = expr; }
10101 auto *FirstExpr = dyn_cast<Expr>(First);
10102 auto *SecondExpr = dyn_cast<Expr>(Second);
10103 if (!FirstExpr || !SecondExpr ||
10104 !(FirstExpr->isInstantiationDependent() ||
10105 SecondExpr->isInstantiationDependent())) {
10106 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10107 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10108 ErrorFound = NotAnAssignmentOp;
10109 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10110 : First->getBeginLoc();
10111 NoteRange = ErrorRange = FirstBinOp
10112 ? FirstBinOp->getSourceRange()
10113 : SourceRange(ErrorLoc, ErrorLoc);
10114 } else {
10115 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10116 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10117 ErrorFound = NotAnAssignmentOp;
10118 NoteLoc = ErrorLoc = SecondBinOp
10119 ? SecondBinOp->getOperatorLoc()
10120 : Second->getBeginLoc();
10121 NoteRange = ErrorRange =
10122 SecondBinOp ? SecondBinOp->getSourceRange()
10123 : SourceRange(ErrorLoc, ErrorLoc);
10124 } else {
10125 Expr *PossibleXRHSInFirst =
10126 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10127 Expr *PossibleXLHSInSecond =
10128 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10129 llvm::FoldingSetNodeID X1Id, X2Id;
10130 PossibleXRHSInFirst->Profile(X1Id, Context,
10131 /*Canonical=*/true);
10132 PossibleXLHSInSecond->Profile(X2Id, Context,
10133 /*Canonical=*/true);
10134 IsUpdateExprFound = X1Id == X2Id;
10135 if (IsUpdateExprFound) {
10136 V = FirstBinOp->getLHS();
10137 X = SecondBinOp->getLHS();
10138 E = SecondBinOp->getRHS();
10139 UE = nullptr;
10140 IsXLHSInRHSPart = false;
10141 IsPostfixUpdate = true;
10142 } else {
10143 ErrorFound = NotASpecificExpression;
10144 ErrorLoc = FirstBinOp->getExprLoc();
10145 ErrorRange = FirstBinOp->getSourceRange();
10146 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10147 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10148 }
10149 }
10150 }
10151 }
10152 }
10153 } else {
10154 NoteLoc = ErrorLoc = Body->getBeginLoc();
10155 NoteRange = ErrorRange =
10156 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10157 ErrorFound = NotTwoSubstatements;
10158 }
10159 } else {
10160 NoteLoc = ErrorLoc = Body->getBeginLoc();
10161 NoteRange = ErrorRange =
10162 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10163 ErrorFound = NotACompoundStatement;
10164 }
10165 if (ErrorFound != NoError) {
10166 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10167 << ErrorRange;
10168 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10169 return StmtError();
10170 }
10171 if (CurContext->isDependentContext())
10172 UE = V = E = X = nullptr;
10173 }
10174 }
10175
10176 setFunctionHasBranchProtectedScope();
10177
10178 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10179 X, V, E, UE, IsXLHSInRHSPart,
10180 IsPostfixUpdate);
10181}
10182
10183StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10184 Stmt *AStmt,
10185 SourceLocation StartLoc,
10186 SourceLocation EndLoc) {
10187 if (!AStmt)
10188 return StmtError();
10189
10190 auto *CS = cast<CapturedStmt>(AStmt);
10191 // 1.2.2 OpenMP Language Terminology
10192 // Structured block - An executable statement with a single entry at the
10193 // top and a single exit at the bottom.
10194 // The point of exit cannot be a branch out of the structured block.
10195 // longjmp() and throw() must not violate the entry/exit criteria.
10196 CS->getCapturedDecl()->setNothrow();
10197 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10198 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10199 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10200 // 1.2.2 OpenMP Language Terminology
10201 // Structured block - An executable statement with a single entry at the
10202 // top and a single exit at the bottom.
10203 // The point of exit cannot be a branch out of the structured block.
10204 // longjmp() and throw() must not violate the entry/exit criteria.
10205 CS->getCapturedDecl()->setNothrow();
10206 }
10207
10208 // OpenMP [2.16, Nesting of Regions]
10209 // If specified, a teams construct must be contained within a target
10210 // construct. That target construct must contain no statements or directives
10211 // outside of the teams construct.
10212 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
10213 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10214 bool OMPTeamsFound = true;
10215 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10216 auto I = CS->body_begin();
10217 while (I != CS->body_end()) {
10218 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10219 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10220 OMPTeamsFound) {
10221
10222 OMPTeamsFound = false;
10223 break;
10224 }
10225 ++I;
10226 }
10227 assert(I != CS->body_end() && "Not found statement")((I != CS->body_end() && "Not found statement") ? static_cast
<void> (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10227, __PRETTY_FUNCTION__))
;
10228 S = *I;
10229 } else {
10230 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10231 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10232 }
10233 if (!OMPTeamsFound) {
10234 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10235 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
10236 diag::note_omp_nested_teams_construct_here);
10237 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10238 << isa<OMPExecutableDirective>(S);
10239 return StmtError();
10240 }
10241 }
10242
10243 setFunctionHasBranchProtectedScope();
10244
10245 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10246}
10247
10248StmtResult
10249Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10250 Stmt *AStmt, SourceLocation StartLoc,
10251 SourceLocation EndLoc) {
10252 if (!AStmt)
10253 return StmtError();
10254
10255 auto *CS = cast<CapturedStmt>(AStmt);
10256 // 1.2.2 OpenMP Language Terminology
10257 // Structured block - An executable statement with a single entry at the
10258 // top and a single exit at the bottom.
10259 // The point of exit cannot be a branch out of the structured block.
10260 // longjmp() and throw() must not violate the entry/exit criteria.
10261 CS->getCapturedDecl()->setNothrow();
10262 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10263 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10264 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10265 // 1.2.2 OpenMP Language Terminology
10266 // Structured block - An executable statement with a single entry at the
10267 // top and a single exit at the bottom.
10268 // The point of exit cannot be a branch out of the structured block.
10269 // longjmp() and throw() must not violate the entry/exit criteria.
10270 CS->getCapturedDecl()->setNothrow();
10271 }
10272
10273 setFunctionHasBranchProtectedScope();
10274
10275 return OMPTargetParallelDirective::Create(
10276 Context, StartLoc, EndLoc, Clauses, AStmt,
10277 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10278}
10279
10280StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10281 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10282 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10283 if (!AStmt)
10284 return StmtError();
10285
10286 auto *CS = cast<CapturedStmt>(AStmt);
10287 // 1.2.2 OpenMP Language Terminology
10288 // Structured block - An executable statement with a single entry at the
10289 // top and a single exit at the bottom.
10290 // The point of exit cannot be a branch out of the structured block.
10291 // longjmp() and throw() must not violate the entry/exit criteria.
10292 CS->getCapturedDecl()->setNothrow();
10293 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10294 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10295 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10296 // 1.2.2 OpenMP Language Terminology
10297 // Structured block - An executable statement with a single entry at the
10298 // top and a single exit at the bottom.
10299 // The point of exit cannot be a branch out of the structured block.
10300 // longjmp() and throw() must not violate the entry/exit criteria.
10301 CS->getCapturedDecl()->setNothrow();
10302 }
10303
10304 OMPLoopDirective::HelperExprs B;
10305 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10306 // define the nested loops number.
10307 unsigned NestedLoopCount =
10308 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10309 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10310 VarsWithImplicitDSA, B);
10311 if (NestedLoopCount == 0)
10312 return StmtError();
10313
10314 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10315, __PRETTY_FUNCTION__))
10315 "omp target parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10315, __PRETTY_FUNCTION__))
;
10316
10317 if (!CurContext->isDependentContext()) {
10318 // Finalize the clauses that need pre-built expressions for CodeGen.
10319 for (OMPClause *C : Clauses) {
10320 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10321 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10322 B.NumIterations, *this, CurScope,
10323 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10324 return StmtError();
10325 }
10326 }
10327
10328 setFunctionHasBranchProtectedScope();
10329 return OMPTargetParallelForDirective::Create(
10330 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10331 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10332}
10333
10334/// Check for existence of a map clause in the list of clauses.
10335static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10336 const OpenMPClauseKind K) {
10337 return llvm::any_of(
10338 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10339}
10340
10341template <typename... Params>
10342static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10343 const Params... ClauseTypes) {
10344 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10345}
10346
10347StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10348 Stmt *AStmt,
10349 SourceLocation StartLoc,
10350 SourceLocation EndLoc) {
10351 if (!AStmt)
10352 return StmtError();
10353
10354 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10354, __PRETTY_FUNCTION__))
;
10355
10356 // OpenMP [2.12.2, target data Construct, Restrictions]
10357 // At least one map, use_device_addr or use_device_ptr clause must appear on
10358 // the directive.
10359 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10360 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10361 StringRef Expected;
10362 if (LangOpts.OpenMP < 50)
10363 Expected = "'map' or 'use_device_ptr'";
10364 else
10365 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10366 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10367 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10368 return StmtError();
10369 }
10370
10371 setFunctionHasBranchProtectedScope();
10372
10373 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10374 AStmt);
10375}
10376
10377StmtResult
10378Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10379 SourceLocation StartLoc,
10380 SourceLocation EndLoc, Stmt *AStmt) {
10381 if (!AStmt)
10382 return StmtError();
10383
10384 auto *CS = cast<CapturedStmt>(AStmt);
10385 // 1.2.2 OpenMP Language Terminology
10386 // Structured block - An executable statement with a single entry at the
10387 // top and a single exit at the bottom.
10388 // The point of exit cannot be a branch out of the structured block.
10389 // longjmp() and throw() must not violate the entry/exit criteria.
10390 CS->getCapturedDecl()->setNothrow();
10391 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10392 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10393 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10394 // 1.2.2 OpenMP Language Terminology
10395 // Structured block - An executable statement with a single entry at the
10396 // top and a single exit at the bottom.
10397 // The point of exit cannot be a branch out of the structured block.
10398 // longjmp() and throw() must not violate the entry/exit criteria.
10399 CS->getCapturedDecl()->setNothrow();
10400 }
10401
10402 // OpenMP [2.10.2, Restrictions, p. 99]
10403 // At least one map clause must appear on the directive.
10404 if (!hasClauses(Clauses, OMPC_map)) {
10405 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10406 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10407 return StmtError();
10408 }
10409
10410 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10411 AStmt);
10412}
10413
10414StmtResult
10415Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10416 SourceLocation StartLoc,
10417 SourceLocation EndLoc, Stmt *AStmt) {
10418 if (!AStmt)
10419 return StmtError();
10420
10421 auto *CS = cast<CapturedStmt>(AStmt);
10422 // 1.2.2 OpenMP Language Terminology
10423 // Structured block - An executable statement with a single entry at the
10424 // top and a single exit at the bottom.
10425 // The point of exit cannot be a branch out of the structured block.
10426 // longjmp() and throw() must not violate the entry/exit criteria.
10427 CS->getCapturedDecl()->setNothrow();
10428 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10429 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10430 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10431 // 1.2.2 OpenMP Language Terminology
10432 // Structured block - An executable statement with a single entry at the
10433 // top and a single exit at the bottom.
10434 // The point of exit cannot be a branch out of the structured block.
10435 // longjmp() and throw() must not violate the entry/exit criteria.
10436 CS->getCapturedDecl()->setNothrow();
10437 }
10438
10439 // OpenMP [2.10.3, Restrictions, p. 102]
10440 // At least one map clause must appear on the directive.
10441 if (!hasClauses(Clauses, OMPC_map)) {
10442 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10443 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10444 return StmtError();
10445 }
10446
10447 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10448 AStmt);
10449}
10450
10451StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10452 SourceLocation StartLoc,
10453 SourceLocation EndLoc,
10454 Stmt *AStmt) {
10455 if (!AStmt)
10456 return StmtError();
10457
10458 auto *CS = cast<CapturedStmt>(AStmt);
10459 // 1.2.2 OpenMP Language Terminology
10460 // Structured block - An executable statement with a single entry at the
10461 // top and a single exit at the bottom.
10462 // The point of exit cannot be a branch out of the structured block.
10463 // longjmp() and throw() must not violate the entry/exit criteria.
10464 CS->getCapturedDecl()->setNothrow();
10465 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10466 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10467 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10468 // 1.2.2 OpenMP Language Terminology
10469 // Structured block - An executable statement with a single entry at the
10470 // top and a single exit at the bottom.
10471 // The point of exit cannot be a branch out of the structured block.
10472 // longjmp() and throw() must not violate the entry/exit criteria.
10473 CS->getCapturedDecl()->setNothrow();
10474 }
10475
10476 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10477 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10478 return StmtError();
10479 }
10480 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10481 AStmt);
10482}
10483
10484StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10485 Stmt *AStmt, SourceLocation StartLoc,
10486 SourceLocation EndLoc) {
10487 if (!AStmt)
10488 return StmtError();
10489
10490 auto *CS = cast<CapturedStmt>(AStmt);
10491 // 1.2.2 OpenMP Language Terminology
10492 // Structured block - An executable statement with a single entry at the
10493 // top and a single exit at the bottom.
10494 // The point of exit cannot be a branch out of the structured block.
10495 // longjmp() and throw() must not violate the entry/exit criteria.
10496 CS->getCapturedDecl()->setNothrow();
10497
10498 setFunctionHasBranchProtectedScope();
10499
10500 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10501
10502 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10503}
10504
10505StmtResult
10506Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10507 SourceLocation EndLoc,
10508 OpenMPDirectiveKind CancelRegion) {
10509 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10510 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10511 return StmtError();
10512 }
10513 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10514 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10515 return StmtError();
10516 }
10517 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10518 CancelRegion);
10519}
10520
10521StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10522 SourceLocation StartLoc,
10523 SourceLocation EndLoc,
10524 OpenMPDirectiveKind CancelRegion) {
10525 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
10526 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10527 return StmtError();
10528 }
10529 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
10530 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10531 return StmtError();
10532 }
10533 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
10534 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10535 CancelRegion);
10536}
10537
10538static bool checkGrainsizeNumTasksClauses(Sema &S,
10539 ArrayRef<OMPClause *> Clauses) {
10540 const OMPClause *PrevClause = nullptr;
10541 bool ErrorFound = false;
10542 for (const OMPClause *C : Clauses) {
10543 if (C->getClauseKind() == OMPC_grainsize ||
10544 C->getClauseKind() == OMPC_num_tasks) {
10545 if (!PrevClause)
10546 PrevClause = C;
10547 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10548 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10549 << getOpenMPClauseName(C->getClauseKind())
10550 << getOpenMPClauseName(PrevClause->getClauseKind());
10551 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10552 << getOpenMPClauseName(PrevClause->getClauseKind());
10553 ErrorFound = true;
10554 }
10555 }
10556 }
10557 return ErrorFound;
10558}
10559
10560static bool checkReductionClauseWithNogroup(Sema &S,
10561 ArrayRef<OMPClause *> Clauses) {
10562 const OMPClause *ReductionClause = nullptr;
10563 const OMPClause *NogroupClause = nullptr;
10564 for (const OMPClause *C : Clauses) {
10565 if (C->getClauseKind() == OMPC_reduction) {
10566 ReductionClause = C;
10567 if (NogroupClause)
10568 break;
10569 continue;
10570 }
10571 if (C->getClauseKind() == OMPC_nogroup) {
10572 NogroupClause = C;
10573 if (ReductionClause)
10574 break;
10575 continue;
10576 }
10577 }
10578 if (ReductionClause && NogroupClause) {
10579 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10580 << SourceRange(NogroupClause->getBeginLoc(),
10581 NogroupClause->getEndLoc());
10582 return true;
10583 }
10584 return false;
10585}
10586
10587StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10590 if (!AStmt)
10591 return StmtError();
10592
10593 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10593, __PRETTY_FUNCTION__))
;
10594 OMPLoopDirective::HelperExprs B;
10595 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10596 // define the nested loops number.
10597 unsigned NestedLoopCount =
10598 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10599 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10600 VarsWithImplicitDSA, B);
10601 if (NestedLoopCount == 0)
10602 return StmtError();
10603
10604 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10605, __PRETTY_FUNCTION__))
10605 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10605, __PRETTY_FUNCTION__))
;
10606
10607 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10608 // The grainsize clause and num_tasks clause are mutually exclusive and may
10609 // not appear on the same taskloop directive.
10610 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10611 return StmtError();
10612 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10613 // If a reduction clause is present on the taskloop directive, the nogroup
10614 // clause must not be specified.
10615 if (checkReductionClauseWithNogroup(*this, Clauses))
10616 return StmtError();
10617
10618 setFunctionHasBranchProtectedScope();
10619 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10620 NestedLoopCount, Clauses, AStmt, B,
10621 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10622}
10623
10624StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10625 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10626 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10627 if (!AStmt)
10628 return StmtError();
10629
10630 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10630, __PRETTY_FUNCTION__))
;
10631 OMPLoopDirective::HelperExprs B;
10632 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10633 // define the nested loops number.
10634 unsigned NestedLoopCount =
10635 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10636 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10637 VarsWithImplicitDSA, B);
10638 if (NestedLoopCount == 0)
10639 return StmtError();
10640
10641 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10642, __PRETTY_FUNCTION__))
10642 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10642, __PRETTY_FUNCTION__))
;
10643
10644 if (!CurContext->isDependentContext()) {
10645 // Finalize the clauses that need pre-built expressions for CodeGen.
10646 for (OMPClause *C : Clauses) {
10647 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10648 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10649 B.NumIterations, *this, CurScope,
10650 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10651 return StmtError();
10652 }
10653 }
10654
10655 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10656 // The grainsize clause and num_tasks clause are mutually exclusive and may
10657 // not appear on the same taskloop directive.
10658 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10659 return StmtError();
10660 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10661 // If a reduction clause is present on the taskloop directive, the nogroup
10662 // clause must not be specified.
10663 if (checkReductionClauseWithNogroup(*this, Clauses))
10664 return StmtError();
10665 if (checkSimdlenSafelenSpecified(*this, Clauses))
10666 return StmtError();
10667
10668 setFunctionHasBranchProtectedScope();
10669 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10670 NestedLoopCount, Clauses, AStmt, B);
10671}
10672
10673StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10674 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10675 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10676 if (!AStmt)
10677 return StmtError();
10678
10679 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10679, __PRETTY_FUNCTION__))
;
10680 OMPLoopDirective::HelperExprs B;
10681 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10682 // define the nested loops number.
10683 unsigned NestedLoopCount =
10684 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10685 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10686 VarsWithImplicitDSA, B);
10687 if (NestedLoopCount == 0)
10688 return StmtError();
10689
10690 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10691, __PRETTY_FUNCTION__))
10691 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10691, __PRETTY_FUNCTION__))
;
10692
10693 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10694 // The grainsize clause and num_tasks clause are mutually exclusive and may
10695 // not appear on the same taskloop directive.
10696 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10697 return StmtError();
10698 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10699 // If a reduction clause is present on the taskloop directive, the nogroup
10700 // clause must not be specified.
10701 if (checkReductionClauseWithNogroup(*this, Clauses))
10702 return StmtError();
10703
10704 setFunctionHasBranchProtectedScope();
10705 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10706 NestedLoopCount, Clauses, AStmt, B,
10707 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10708}
10709
10710StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10711 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10712 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10713 if (!AStmt)
10714 return StmtError();
10715
10716 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10716, __PRETTY_FUNCTION__))
;
10717 OMPLoopDirective::HelperExprs B;
10718 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10719 // define the nested loops number.
10720 unsigned NestedLoopCount =
10721 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10722 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10723 VarsWithImplicitDSA, B);
10724 if (NestedLoopCount == 0)
10725 return StmtError();
10726
10727 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10728, __PRETTY_FUNCTION__))
10728 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10728, __PRETTY_FUNCTION__))
;
10729
10730 if (!CurContext->isDependentContext()) {
10731 // Finalize the clauses that need pre-built expressions for CodeGen.
10732 for (OMPClause *C : Clauses) {
10733 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10734 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10735 B.NumIterations, *this, CurScope,
10736 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10737 return StmtError();
10738 }
10739 }
10740
10741 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10742 // The grainsize clause and num_tasks clause are mutually exclusive and may
10743 // not appear on the same taskloop directive.
10744 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10745 return StmtError();
10746 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10747 // If a reduction clause is present on the taskloop directive, the nogroup
10748 // clause must not be specified.
10749 if (checkReductionClauseWithNogroup(*this, Clauses))
10750 return StmtError();
10751 if (checkSimdlenSafelenSpecified(*this, Clauses))
10752 return StmtError();
10753
10754 setFunctionHasBranchProtectedScope();
10755 return OMPMasterTaskLoopSimdDirective::Create(
10756 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10757}
10758
10759StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10760 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10761 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10762 if (!AStmt)
10763 return StmtError();
10764
10765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10765, __PRETTY_FUNCTION__))
;
10766 auto *CS = cast<CapturedStmt>(AStmt);
10767 // 1.2.2 OpenMP Language Terminology
10768 // Structured block - An executable statement with a single entry at the
10769 // top and a single exit at the bottom.
10770 // The point of exit cannot be a branch out of the structured block.
10771 // longjmp() and throw() must not violate the entry/exit criteria.
10772 CS->getCapturedDecl()->setNothrow();
10773 for (int ThisCaptureLevel =
10774 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10775 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10776 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10777 // 1.2.2 OpenMP Language Terminology
10778 // Structured block - An executable statement with a single entry at the
10779 // top and a single exit at the bottom.
10780 // The point of exit cannot be a branch out of the structured block.
10781 // longjmp() and throw() must not violate the entry/exit criteria.
10782 CS->getCapturedDecl()->setNothrow();
10783 }
10784
10785 OMPLoopDirective::HelperExprs B;
10786 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10787 // define the nested loops number.
10788 unsigned NestedLoopCount = checkOpenMPLoop(
10789 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10790 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10791 VarsWithImplicitDSA, B);
10792 if (NestedLoopCount == 0)
10793 return StmtError();
10794
10795 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10796, __PRETTY_FUNCTION__))
10796 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10796, __PRETTY_FUNCTION__))
;
10797
10798 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10799 // The grainsize clause and num_tasks clause are mutually exclusive and may
10800 // not appear on the same taskloop directive.
10801 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10802 return StmtError();
10803 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10804 // If a reduction clause is present on the taskloop directive, the nogroup
10805 // clause must not be specified.
10806 if (checkReductionClauseWithNogroup(*this, Clauses))
10807 return StmtError();
10808
10809 setFunctionHasBranchProtectedScope();
10810 return OMPParallelMasterTaskLoopDirective::Create(
10811 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10812 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10813}
10814
10815StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10816 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10817 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10818 if (!AStmt)
10819 return StmtError();
10820
10821 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10821, __PRETTY_FUNCTION__))
;
10822 auto *CS = cast<CapturedStmt>(AStmt);
10823 // 1.2.2 OpenMP Language Terminology
10824 // Structured block - An executable statement with a single entry at the
10825 // top and a single exit at the bottom.
10826 // The point of exit cannot be a branch out of the structured block.
10827 // longjmp() and throw() must not violate the entry/exit criteria.
10828 CS->getCapturedDecl()->setNothrow();
10829 for (int ThisCaptureLevel =
10830 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10831 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10832 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10833 // 1.2.2 OpenMP Language Terminology
10834 // Structured block - An executable statement with a single entry at the
10835 // top and a single exit at the bottom.
10836 // The point of exit cannot be a branch out of the structured block.
10837 // longjmp() and throw() must not violate the entry/exit criteria.
10838 CS->getCapturedDecl()->setNothrow();
10839 }
10840
10841 OMPLoopDirective::HelperExprs B;
10842 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10843 // define the nested loops number.
10844 unsigned NestedLoopCount = checkOpenMPLoop(
10845 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10846 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10847 VarsWithImplicitDSA, B);
10848 if (NestedLoopCount == 0)
10849 return StmtError();
10850
10851 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10852, __PRETTY_FUNCTION__))
10852 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10852, __PRETTY_FUNCTION__))
;
10853
10854 if (!CurContext->isDependentContext()) {
10855 // Finalize the clauses that need pre-built expressions for CodeGen.
10856 for (OMPClause *C : Clauses) {
10857 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10858 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10859 B.NumIterations, *this, CurScope,
10860 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10861 return StmtError();
10862 }
10863 }
10864
10865 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10866 // The grainsize clause and num_tasks clause are mutually exclusive and may
10867 // not appear on the same taskloop directive.
10868 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10869 return StmtError();
10870 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10871 // If a reduction clause is present on the taskloop directive, the nogroup
10872 // clause must not be specified.
10873 if (checkReductionClauseWithNogroup(*this, Clauses))
10874 return StmtError();
10875 if (checkSimdlenSafelenSpecified(*this, Clauses))
10876 return StmtError();
10877
10878 setFunctionHasBranchProtectedScope();
10879 return OMPParallelMasterTaskLoopSimdDirective::Create(
10880 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10881}
10882
10883StmtResult Sema::ActOnOpenMPDistributeDirective(
10884 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10885 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10886 if (!AStmt)
10887 return StmtError();
10888
10889 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10889, __PRETTY_FUNCTION__))
;
10890 OMPLoopDirective::HelperExprs B;
10891 // In presence of clause 'collapse' with number of loops, it will
10892 // define the nested loops number.
10893 unsigned NestedLoopCount =
10894 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
10895 nullptr /*ordered not a clause on distribute*/, AStmt,
10896 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10897 if (NestedLoopCount == 0)
10898 return StmtError();
10899
10900 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10901, __PRETTY_FUNCTION__))
10901 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10901, __PRETTY_FUNCTION__))
;
10902
10903 setFunctionHasBranchProtectedScope();
10904 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
10905 NestedLoopCount, Clauses, AStmt, B);
10906}
10907
10908StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
10909 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10910 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10911 if (!AStmt)
10912 return StmtError();
10913
10914 auto *CS = cast<CapturedStmt>(AStmt);
10915 // 1.2.2 OpenMP Language Terminology
10916 // Structured block - An executable statement with a single entry at the
10917 // top and a single exit at the bottom.
10918 // The point of exit cannot be a branch out of the structured block.
10919 // longjmp() and throw() must not violate the entry/exit criteria.
10920 CS->getCapturedDecl()->setNothrow();
10921 for (int ThisCaptureLevel =
10922 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
10923 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10924 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10925 // 1.2.2 OpenMP Language Terminology
10926 // Structured block - An executable statement with a single entry at the
10927 // top and a single exit at the bottom.
10928 // The point of exit cannot be a branch out of the structured block.
10929 // longjmp() and throw() must not violate the entry/exit criteria.
10930 CS->getCapturedDecl()->setNothrow();
10931 }
10932
10933 OMPLoopDirective::HelperExprs B;
10934 // In presence of clause 'collapse' with number of loops, it will
10935 // define the nested loops number.
10936 unsigned NestedLoopCount = checkOpenMPLoop(
10937 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10938 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10939 VarsWithImplicitDSA, B);
10940 if (NestedLoopCount == 0)
10941 return StmtError();
10942
10943 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10944, __PRETTY_FUNCTION__))
10944 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10944, __PRETTY_FUNCTION__))
;
10945
10946 setFunctionHasBranchProtectedScope();
10947 return OMPDistributeParallelForDirective::Create(
10948 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10949 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10950}
10951
10952StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
10953 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10954 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10955 if (!AStmt)
10956 return StmtError();
10957
10958 auto *CS = cast<CapturedStmt>(AStmt);
10959 // 1.2.2 OpenMP Language Terminology
10960 // Structured block - An executable statement with a single entry at the
10961 // top and a single exit at the bottom.
10962 // The point of exit cannot be a branch out of the structured block.
10963 // longjmp() and throw() must not violate the entry/exit criteria.
10964 CS->getCapturedDecl()->setNothrow();
10965 for (int ThisCaptureLevel =
10966 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10967 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10968 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10969 // 1.2.2 OpenMP Language Terminology
10970 // Structured block - An executable statement with a single entry at the
10971 // top and a single exit at the bottom.
10972 // The point of exit cannot be a branch out of the structured block.
10973 // longjmp() and throw() must not violate the entry/exit criteria.
10974 CS->getCapturedDecl()->setNothrow();
10975 }
10976
10977 OMPLoopDirective::HelperExprs B;
10978 // In presence of clause 'collapse' with number of loops, it will
10979 // define the nested loops number.
10980 unsigned NestedLoopCount = checkOpenMPLoop(
10981 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10982 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10983 VarsWithImplicitDSA, B);
10984 if (NestedLoopCount == 0)
10985 return StmtError();
10986
10987 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10988, __PRETTY_FUNCTION__))
10988 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 10988, __PRETTY_FUNCTION__))
;
10989
10990 if (!CurContext->isDependentContext()) {
10991 // Finalize the clauses that need pre-built expressions for CodeGen.
10992 for (OMPClause *C : Clauses) {
10993 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10994 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10995 B.NumIterations, *this, CurScope,
10996 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10997 return StmtError();
10998 }
10999 }
11000
11001 if (checkSimdlenSafelenSpecified(*this, Clauses))
11002 return StmtError();
11003
11004 setFunctionHasBranchProtectedScope();
11005 return OMPDistributeParallelForSimdDirective::Create(
11006 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11007}
11008
11009StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11010 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11011 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11012 if (!AStmt)
11013 return StmtError();
11014
11015 auto *CS = cast<CapturedStmt>(AStmt);
11016 // 1.2.2 OpenMP Language Terminology
11017 // Structured block - An executable statement with a single entry at the
11018 // top and a single exit at the bottom.
11019 // The point of exit cannot be a branch out of the structured block.
11020 // longjmp() and throw() must not violate the entry/exit criteria.
11021 CS->getCapturedDecl()->setNothrow();
11022 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11023 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11024 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11025 // 1.2.2 OpenMP Language Terminology
11026 // Structured block - An executable statement with a single entry at the
11027 // top and a single exit at the bottom.
11028 // The point of exit cannot be a branch out of the structured block.
11029 // longjmp() and throw() must not violate the entry/exit criteria.
11030 CS->getCapturedDecl()->setNothrow();
11031 }
11032
11033 OMPLoopDirective::HelperExprs B;
11034 // In presence of clause 'collapse' with number of loops, it will
11035 // define the nested loops number.
11036 unsigned NestedLoopCount =
11037 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11038 nullptr /*ordered not a clause on distribute*/, CS, *this,
11039 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11040 if (NestedLoopCount == 0)
11041 return StmtError();
11042
11043 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11044, __PRETTY_FUNCTION__))
11044 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11044, __PRETTY_FUNCTION__))
;
11045
11046 if (!CurContext->isDependentContext()) {
11047 // Finalize the clauses that need pre-built expressions for CodeGen.
11048 for (OMPClause *C : Clauses) {
11049 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11050 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11051 B.NumIterations, *this, CurScope,
11052 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11053 return StmtError();
11054 }
11055 }
11056
11057 if (checkSimdlenSafelenSpecified(*this, Clauses))
11058 return StmtError();
11059
11060 setFunctionHasBranchProtectedScope();
11061 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11062 NestedLoopCount, Clauses, AStmt, B);
11063}
11064
11065StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11066 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11067 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11068 if (!AStmt)
11069 return StmtError();
11070
11071 auto *CS = cast<CapturedStmt>(AStmt);
11072 // 1.2.2 OpenMP Language Terminology
11073 // Structured block - An executable statement with a single entry at the
11074 // top and a single exit at the bottom.
11075 // The point of exit cannot be a branch out of the structured block.
11076 // longjmp() and throw() must not violate the entry/exit criteria.
11077 CS->getCapturedDecl()->setNothrow();
11078 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11079 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11080 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11081 // 1.2.2 OpenMP Language Terminology
11082 // Structured block - An executable statement with a single entry at the
11083 // top and a single exit at the bottom.
11084 // The point of exit cannot be a branch out of the structured block.
11085 // longjmp() and throw() must not violate the entry/exit criteria.
11086 CS->getCapturedDecl()->setNothrow();
11087 }
11088
11089 OMPLoopDirective::HelperExprs B;
11090 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11091 // define the nested loops number.
11092 unsigned NestedLoopCount = checkOpenMPLoop(
11093 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11094 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11095 VarsWithImplicitDSA, B);
11096 if (NestedLoopCount == 0)
11097 return StmtError();
11098
11099 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11100, __PRETTY_FUNCTION__))
11100 "omp target parallel for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target parallel for simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11100, __PRETTY_FUNCTION__))
;
11101
11102 if (!CurContext->isDependentContext()) {
11103 // Finalize the clauses that need pre-built expressions for CodeGen.
11104 for (OMPClause *C : Clauses) {
11105 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11107 B.NumIterations, *this, CurScope,
11108 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11109 return StmtError();
11110 }
11111 }
11112 if (checkSimdlenSafelenSpecified(*this, Clauses))
11113 return StmtError();
11114
11115 setFunctionHasBranchProtectedScope();
11116 return OMPTargetParallelForSimdDirective::Create(
11117 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11118}
11119
11120StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11121 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11122 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11123 if (!AStmt)
11124 return StmtError();
11125
11126 auto *CS = cast<CapturedStmt>(AStmt);
11127 // 1.2.2 OpenMP Language Terminology
11128 // Structured block - An executable statement with a single entry at the
11129 // top and a single exit at the bottom.
11130 // The point of exit cannot be a branch out of the structured block.
11131 // longjmp() and throw() must not violate the entry/exit criteria.
11132 CS->getCapturedDecl()->setNothrow();
11133 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11134 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11135 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11136 // 1.2.2 OpenMP Language Terminology
11137 // Structured block - An executable statement with a single entry at the
11138 // top and a single exit at the bottom.
11139 // The point of exit cannot be a branch out of the structured block.
11140 // longjmp() and throw() must not violate the entry/exit criteria.
11141 CS->getCapturedDecl()->setNothrow();
11142 }
11143
11144 OMPLoopDirective::HelperExprs B;
11145 // In presence of clause 'collapse' with number of loops, it will define the
11146 // nested loops number.
11147 unsigned NestedLoopCount =
11148 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11149 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11150 VarsWithImplicitDSA, B);
11151 if (NestedLoopCount == 0)
11152 return StmtError();
11153
11154 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11155, __PRETTY_FUNCTION__))
11155 "omp target simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target simd loop exprs were not built") ? static_cast<
void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11155, __PRETTY_FUNCTION__))
;
11156
11157 if (!CurContext->isDependentContext()) {
11158 // Finalize the clauses that need pre-built expressions for CodeGen.
11159 for (OMPClause *C : Clauses) {
11160 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11162 B.NumIterations, *this, CurScope,
11163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11164 return StmtError();
11165 }
11166 }
11167
11168 if (checkSimdlenSafelenSpecified(*this, Clauses))
11169 return StmtError();
11170
11171 setFunctionHasBranchProtectedScope();
11172 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11173 NestedLoopCount, Clauses, AStmt, B);
11174}
11175
11176StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11177 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11178 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11179 if (!AStmt)
11180 return StmtError();
11181
11182 auto *CS = cast<CapturedStmt>(AStmt);
11183 // 1.2.2 OpenMP Language Terminology
11184 // Structured block - An executable statement with a single entry at the
11185 // top and a single exit at the bottom.
11186 // The point of exit cannot be a branch out of the structured block.
11187 // longjmp() and throw() must not violate the entry/exit criteria.
11188 CS->getCapturedDecl()->setNothrow();
11189 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11190 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11191 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11192 // 1.2.2 OpenMP Language Terminology
11193 // Structured block - An executable statement with a single entry at the
11194 // top and a single exit at the bottom.
11195 // The point of exit cannot be a branch out of the structured block.
11196 // longjmp() and throw() must not violate the entry/exit criteria.
11197 CS->getCapturedDecl()->setNothrow();
11198 }
11199
11200 OMPLoopDirective::HelperExprs B;
11201 // In presence of clause 'collapse' with number of loops, it will
11202 // define the nested loops number.
11203 unsigned NestedLoopCount =
11204 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11205 nullptr /*ordered not a clause on distribute*/, CS, *this,
11206 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11207 if (NestedLoopCount == 0)
11208 return StmtError();
11209
11210 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11211, __PRETTY_FUNCTION__))
11211 "omp teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11211, __PRETTY_FUNCTION__))
;
11212
11213 setFunctionHasBranchProtectedScope();
11214
11215 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11216
11217 return OMPTeamsDistributeDirective::Create(
11218 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11219}
11220
11221StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11222 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11223 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11224 if (!AStmt)
11225 return StmtError();
11226
11227 auto *CS = cast<CapturedStmt>(AStmt);
11228 // 1.2.2 OpenMP Language Terminology
11229 // Structured block - An executable statement with a single entry at the
11230 // top and a single exit at the bottom.
11231 // The point of exit cannot be a branch out of the structured block.
11232 // longjmp() and throw() must not violate the entry/exit criteria.
11233 CS->getCapturedDecl()->setNothrow();
11234 for (int ThisCaptureLevel =
11235 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11236 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11237 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11238 // 1.2.2 OpenMP Language Terminology
11239 // Structured block - An executable statement with a single entry at the
11240 // top and a single exit at the bottom.
11241 // The point of exit cannot be a branch out of the structured block.
11242 // longjmp() and throw() must not violate the entry/exit criteria.
11243 CS->getCapturedDecl()->setNothrow();
11244 }
11245
11246 OMPLoopDirective::HelperExprs B;
11247 // In presence of clause 'collapse' with number of loops, it will
11248 // define the nested loops number.
11249 unsigned NestedLoopCount = checkOpenMPLoop(
11250 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11251 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11252 VarsWithImplicitDSA, B);
11253
11254 if (NestedLoopCount == 0)
11255 return StmtError();
11256
11257 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11258, __PRETTY_FUNCTION__))
11258 "omp teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp teams distribute simd loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11258, __PRETTY_FUNCTION__))
;
11259
11260 if (!CurContext->isDependentContext()) {
11261 // Finalize the clauses that need pre-built expressions for CodeGen.
11262 for (OMPClause *C : Clauses) {
11263 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11264 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11265 B.NumIterations, *this, CurScope,
11266 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11267 return StmtError();
11268 }
11269 }
11270
11271 if (checkSimdlenSafelenSpecified(*this, Clauses))
11272 return StmtError();
11273
11274 setFunctionHasBranchProtectedScope();
11275
11276 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11277
11278 return OMPTeamsDistributeSimdDirective::Create(
11279 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11280}
11281
11282StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11283 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11284 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11285 if (!AStmt)
11286 return StmtError();
11287
11288 auto *CS = cast<CapturedStmt>(AStmt);
11289 // 1.2.2 OpenMP Language Terminology
11290 // Structured block - An executable statement with a single entry at the
11291 // top and a single exit at the bottom.
11292 // The point of exit cannot be a branch out of the structured block.
11293 // longjmp() and throw() must not violate the entry/exit criteria.
11294 CS->getCapturedDecl()->setNothrow();
11295
11296 for (int ThisCaptureLevel =
11297 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11298 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11299 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11300 // 1.2.2 OpenMP Language Terminology
11301 // Structured block - An executable statement with a single entry at the
11302 // top and a single exit at the bottom.
11303 // The point of exit cannot be a branch out of the structured block.
11304 // longjmp() and throw() must not violate the entry/exit criteria.
11305 CS->getCapturedDecl()->setNothrow();
11306 }
11307
11308 OMPLoopDirective::HelperExprs B;
11309 // In presence of clause 'collapse' with number of loops, it will
11310 // define the nested loops number.
11311 unsigned NestedLoopCount = checkOpenMPLoop(
11312 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11313 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11314 VarsWithImplicitDSA, B);
11315
11316 if (NestedLoopCount == 0)
11317 return StmtError();
11318
11319 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11320, __PRETTY_FUNCTION__))
11320 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11320, __PRETTY_FUNCTION__))
;
11321
11322 if (!CurContext->isDependentContext()) {
11323 // Finalize the clauses that need pre-built expressions for CodeGen.
11324 for (OMPClause *C : Clauses) {
11325 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11326 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11327 B.NumIterations, *this, CurScope,
11328 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11329 return StmtError();
11330 }
11331 }
11332
11333 if (checkSimdlenSafelenSpecified(*this, Clauses))
11334 return StmtError();
11335
11336 setFunctionHasBranchProtectedScope();
11337
11338 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11339
11340 return OMPTeamsDistributeParallelForSimdDirective::Create(
11341 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11342}
11343
11344StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11345 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11346 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11347 if (!AStmt)
11348 return StmtError();
11349
11350 auto *CS = cast<CapturedStmt>(AStmt);
11351 // 1.2.2 OpenMP Language Terminology
11352 // Structured block - An executable statement with a single entry at the
11353 // top and a single exit at the bottom.
11354 // The point of exit cannot be a branch out of the structured block.
11355 // longjmp() and throw() must not violate the entry/exit criteria.
11356 CS->getCapturedDecl()->setNothrow();
11357
11358 for (int ThisCaptureLevel =
11359 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11360 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11361 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11362 // 1.2.2 OpenMP Language Terminology
11363 // Structured block - An executable statement with a single entry at the
11364 // top and a single exit at the bottom.
11365 // The point of exit cannot be a branch out of the structured block.
11366 // longjmp() and throw() must not violate the entry/exit criteria.
11367 CS->getCapturedDecl()->setNothrow();
11368 }
11369
11370 OMPLoopDirective::HelperExprs B;
11371 // In presence of clause 'collapse' with number of loops, it will
11372 // define the nested loops number.
11373 unsigned NestedLoopCount = checkOpenMPLoop(
11374 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11375 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11376 VarsWithImplicitDSA, B);
11377
11378 if (NestedLoopCount == 0)
11379 return StmtError();
11380
11381 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11382, __PRETTY_FUNCTION__))
11382 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11382, __PRETTY_FUNCTION__))
;
11383
11384 setFunctionHasBranchProtectedScope();
11385
11386 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
11387
11388 return OMPTeamsDistributeParallelForDirective::Create(
11389 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11390 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11391}
11392
11393StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11394 Stmt *AStmt,
11395 SourceLocation StartLoc,
11396 SourceLocation EndLoc) {
11397 if (!AStmt)
11398 return StmtError();
11399
11400 auto *CS = cast<CapturedStmt>(AStmt);
11401 // 1.2.2 OpenMP Language Terminology
11402 // Structured block - An executable statement with a single entry at the
11403 // top and a single exit at the bottom.
11404 // The point of exit cannot be a branch out of the structured block.
11405 // longjmp() and throw() must not violate the entry/exit criteria.
11406 CS->getCapturedDecl()->setNothrow();
11407
11408 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11409 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11410 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11411 // 1.2.2 OpenMP Language Terminology
11412 // Structured block - An executable statement with a single entry at the
11413 // top and a single exit at the bottom.
11414 // The point of exit cannot be a branch out of the structured block.
11415 // longjmp() and throw() must not violate the entry/exit criteria.
11416 CS->getCapturedDecl()->setNothrow();
11417 }
11418 setFunctionHasBranchProtectedScope();
11419
11420 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11421 AStmt);
11422}
11423
11424StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11427 if (!AStmt)
11428 return StmtError();
11429
11430 auto *CS = cast<CapturedStmt>(AStmt);
11431 // 1.2.2 OpenMP Language Terminology
11432 // Structured block - An executable statement with a single entry at the
11433 // top and a single exit at the bottom.
11434 // The point of exit cannot be a branch out of the structured block.
11435 // longjmp() and throw() must not violate the entry/exit criteria.
11436 CS->getCapturedDecl()->setNothrow();
11437 for (int ThisCaptureLevel =
11438 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11439 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11440 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11441 // 1.2.2 OpenMP Language Terminology
11442 // Structured block - An executable statement with a single entry at the
11443 // top and a single exit at the bottom.
11444 // The point of exit cannot be a branch out of the structured block.
11445 // longjmp() and throw() must not violate the entry/exit criteria.
11446 CS->getCapturedDecl()->setNothrow();
11447 }
11448
11449 OMPLoopDirective::HelperExprs B;
11450 // In presence of clause 'collapse' with number of loops, it will
11451 // define the nested loops number.
11452 unsigned NestedLoopCount = checkOpenMPLoop(
11453 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11454 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11455 VarsWithImplicitDSA, B);
11456 if (NestedLoopCount == 0)
11457 return StmtError();
11458
11459 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11460, __PRETTY_FUNCTION__))
11460 "omp target teams distribute loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute loop exprs were not built") ? static_cast
<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11460, __PRETTY_FUNCTION__))
;
11461
11462 setFunctionHasBranchProtectedScope();
11463 return OMPTargetTeamsDistributeDirective::Create(
11464 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11465}
11466
11467StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11468 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11469 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11470 if (!AStmt)
11471 return StmtError();
11472
11473 auto *CS = cast<CapturedStmt>(AStmt);
11474 // 1.2.2 OpenMP Language Terminology
11475 // Structured block - An executable statement with a single entry at the
11476 // top and a single exit at the bottom.
11477 // The point of exit cannot be a branch out of the structured block.
11478 // longjmp() and throw() must not violate the entry/exit criteria.
11479 CS->getCapturedDecl()->setNothrow();
11480 for (int ThisCaptureLevel =
11481 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11482 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11483 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11484 // 1.2.2 OpenMP Language Terminology
11485 // Structured block - An executable statement with a single entry at the
11486 // top and a single exit at the bottom.
11487 // The point of exit cannot be a branch out of the structured block.
11488 // longjmp() and throw() must not violate the entry/exit criteria.
11489 CS->getCapturedDecl()->setNothrow();
11490 }
11491
11492 OMPLoopDirective::HelperExprs B;
11493 // In presence of clause 'collapse' with number of loops, it will
11494 // define the nested loops number.
11495 unsigned NestedLoopCount = checkOpenMPLoop(
11496 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11497 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11498 VarsWithImplicitDSA, B);
11499 if (NestedLoopCount == 0)
11500 return StmtError();
11501
11502 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11503, __PRETTY_FUNCTION__))
11503 "omp target teams distribute parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11503, __PRETTY_FUNCTION__))
;
11504
11505 if (!CurContext->isDependentContext()) {
11506 // Finalize the clauses that need pre-built expressions for CodeGen.
11507 for (OMPClause *C : Clauses) {
11508 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11509 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11510 B.NumIterations, *this, CurScope,
11511 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11512 return StmtError();
11513 }
11514 }
11515
11516 setFunctionHasBranchProtectedScope();
11517 return OMPTargetTeamsDistributeParallelForDirective::Create(
11518 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
11520}
11521
11522StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11523 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11524 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11525 if (!AStmt)
11526 return StmtError();
11527
11528 auto *CS = cast<CapturedStmt>(AStmt);
11529 // 1.2.2 OpenMP Language Terminology
11530 // Structured block - An executable statement with a single entry at the
11531 // top and a single exit at the bottom.
11532 // The point of exit cannot be a branch out of the structured block.
11533 // longjmp() and throw() must not violate the entry/exit criteria.
11534 CS->getCapturedDecl()->setNothrow();
11535 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11536 OMPD_target_teams_distribute_parallel_for_simd);
11537 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11538 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11539 // 1.2.2 OpenMP Language Terminology
11540 // Structured block - An executable statement with a single entry at the
11541 // top and a single exit at the bottom.
11542 // The point of exit cannot be a branch out of the structured block.
11543 // longjmp() and throw() must not violate the entry/exit criteria.
11544 CS->getCapturedDecl()->setNothrow();
11545 }
11546
11547 OMPLoopDirective::HelperExprs B;
11548 // In presence of clause 'collapse' with number of loops, it will
11549 // define the nested loops number.
11550 unsigned NestedLoopCount =
11551 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11552 getCollapseNumberExpr(Clauses),
11553 nullptr /*ordered not a clause on distribute*/, CS, *this,
11554 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
11555 if (NestedLoopCount == 0)
11556 return StmtError();
11557
11558 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11560, __PRETTY_FUNCTION__))
11559 "omp target teams distribute parallel for simd loop exprs were not "(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11560, __PRETTY_FUNCTION__))
11560 "built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute parallel for simd loop exprs were not "
"built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11560, __PRETTY_FUNCTION__))
;
11561
11562 if (!CurContext->isDependentContext()) {
11563 // Finalize the clauses that need pre-built expressions for CodeGen.
11564 for (OMPClause *C : Clauses) {
11565 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11566 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11567 B.NumIterations, *this, CurScope,
11568 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11569 return StmtError();
11570 }
11571 }
11572
11573 if (checkSimdlenSafelenSpecified(*this, Clauses))
11574 return StmtError();
11575
11576 setFunctionHasBranchProtectedScope();
11577 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11578 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11579}
11580
11581StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11582 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11583 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11584 if (!AStmt)
11585 return StmtError();
11586
11587 auto *CS = cast<CapturedStmt>(AStmt);
11588 // 1.2.2 OpenMP Language Terminology
11589 // Structured block - An executable statement with a single entry at the
11590 // top and a single exit at the bottom.
11591 // The point of exit cannot be a branch out of the structured block.
11592 // longjmp() and throw() must not violate the entry/exit criteria.
11593 CS->getCapturedDecl()->setNothrow();
11594 for (int ThisCaptureLevel =
11595 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11596 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11597 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11598 // 1.2.2 OpenMP Language Terminology
11599 // Structured block - An executable statement with a single entry at the
11600 // top and a single exit at the bottom.
11601 // The point of exit cannot be a branch out of the structured block.
11602 // longjmp() and throw() must not violate the entry/exit criteria.
11603 CS->getCapturedDecl()->setNothrow();
11604 }
11605
11606 OMPLoopDirective::HelperExprs B;
11607 // In presence of clause 'collapse' with number of loops, it will
11608 // define the nested loops number.
11609 unsigned NestedLoopCount = checkOpenMPLoop(
11610 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11611 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
11612 VarsWithImplicitDSA, B);
11613 if (NestedLoopCount == 0)
11614 return StmtError();
11615
11616 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11617, __PRETTY_FUNCTION__))
11617 "omp target teams distribute simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp target teams distribute simd loop exprs were not built"
) ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11617, __PRETTY_FUNCTION__))
;
11618
11619 if (!CurContext->isDependentContext()) {
11620 // Finalize the clauses that need pre-built expressions for CodeGen.
11621 for (OMPClause *C : Clauses) {
11622 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11623 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11624 B.NumIterations, *this, CurScope,
11625 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
11626 return StmtError();
11627 }
11628 }
11629
11630 if (checkSimdlenSafelenSpecified(*this, Clauses))
11631 return StmtError();
11632
11633 setFunctionHasBranchProtectedScope();
11634 return OMPTargetTeamsDistributeSimdDirective::Create(
11635 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11636}
11637
11638OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11639 SourceLocation StartLoc,
11640 SourceLocation LParenLoc,
11641 SourceLocation EndLoc) {
11642 OMPClause *Res = nullptr;
11643 switch (Kind) {
11644 case OMPC_final:
11645 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11646 break;
11647 case OMPC_num_threads:
11648 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11649 break;
11650 case OMPC_safelen:
11651 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11652 break;
11653 case OMPC_simdlen:
11654 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11655 break;
11656 case OMPC_allocator:
11657 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11658 break;
11659 case OMPC_collapse:
11660 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11661 break;
11662 case OMPC_ordered:
11663 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11664 break;
11665 case OMPC_num_teams:
11666 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11667 break;
11668 case OMPC_thread_limit:
11669 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11670 break;
11671 case OMPC_priority:
11672 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11673 break;
11674 case OMPC_grainsize:
11675 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11676 break;
11677 case OMPC_num_tasks:
11678 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11679 break;
11680 case OMPC_hint:
11681 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11682 break;
11683 case OMPC_depobj:
11684 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11685 break;
11686 case OMPC_detach:
11687 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11688 break;
11689 case OMPC_device:
11690 case OMPC_if:
11691 case OMPC_default:
11692 case OMPC_proc_bind:
11693 case OMPC_schedule:
11694 case OMPC_private:
11695 case OMPC_firstprivate:
11696 case OMPC_lastprivate:
11697 case OMPC_shared:
11698 case OMPC_reduction:
11699 case OMPC_task_reduction:
11700 case OMPC_in_reduction:
11701 case OMPC_linear:
11702 case OMPC_aligned:
11703 case OMPC_copyin:
11704 case OMPC_copyprivate:
11705 case OMPC_nowait:
11706 case OMPC_untied:
11707 case OMPC_mergeable:
11708 case OMPC_threadprivate:
11709 case OMPC_allocate:
11710 case OMPC_flush:
11711 case OMPC_read:
11712 case OMPC_write:
11713 case OMPC_update:
11714 case OMPC_capture:
11715 case OMPC_seq_cst:
11716 case OMPC_acq_rel:
11717 case OMPC_acquire:
11718 case OMPC_release:
11719 case OMPC_relaxed:
11720 case OMPC_depend:
11721 case OMPC_threads:
11722 case OMPC_simd:
11723 case OMPC_map:
11724 case OMPC_nogroup:
11725 case OMPC_dist_schedule:
11726 case OMPC_defaultmap:
11727 case OMPC_unknown:
11728 case OMPC_uniform:
11729 case OMPC_to:
11730 case OMPC_from:
11731 case OMPC_use_device_ptr:
11732 case OMPC_use_device_addr:
11733 case OMPC_is_device_ptr:
11734 case OMPC_unified_address:
11735 case OMPC_unified_shared_memory:
11736 case OMPC_reverse_offload:
11737 case OMPC_dynamic_allocators:
11738 case OMPC_atomic_default_mem_order:
11739 case OMPC_device_type:
11740 case OMPC_match:
11741 case OMPC_nontemporal:
11742 case OMPC_order:
11743 case OMPC_destroy:
11744 case OMPC_inclusive:
11745 case OMPC_exclusive:
11746 case OMPC_uses_allocators:
11747 case OMPC_affinity:
11748 default:
11749 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11749)
;
11750 }
11751 return Res;
11752}
11753
11754// An OpenMP directive such as 'target parallel' has two captured regions:
11755// for the 'target' and 'parallel' respectively. This function returns
11756// the region in which to capture expressions associated with a clause.
11757// A return value of OMPD_unknown signifies that the expression should not
11758// be captured.
11759static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11760 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11761 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11762 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11763 switch (CKind) {
11764 case OMPC_if:
11765 switch (DKind) {
11766 case OMPD_target_parallel_for_simd:
11767 if (OpenMPVersion >= 50 &&
11768 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11769 CaptureRegion = OMPD_parallel;
11770 break;
11771 }
11772 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11773 case OMPD_target_parallel:
11774 case OMPD_target_parallel_for:
11775 // If this clause applies to the nested 'parallel' region, capture within
11776 // the 'target' region, otherwise do not capture.
11777 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11778 CaptureRegion = OMPD_target;
11779 break;
11780 case OMPD_target_teams_distribute_parallel_for_simd:
11781 if (OpenMPVersion >= 50 &&
11782 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11783 CaptureRegion = OMPD_parallel;
11784 break;
11785 }
11786 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11787 case OMPD_target_teams_distribute_parallel_for:
11788 // If this clause applies to the nested 'parallel' region, capture within
11789 // the 'teams' region, otherwise do not capture.
11790 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11791 CaptureRegion = OMPD_teams;
11792 break;
11793 case OMPD_teams_distribute_parallel_for_simd:
11794 if (OpenMPVersion >= 50 &&
11795 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11796 CaptureRegion = OMPD_parallel;
11797 break;
11798 }
11799 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11800 case OMPD_teams_distribute_parallel_for:
11801 CaptureRegion = OMPD_teams;
11802 break;
11803 case OMPD_target_update:
11804 case OMPD_target_enter_data:
11805 case OMPD_target_exit_data:
11806 CaptureRegion = OMPD_task;
11807 break;
11808 case OMPD_parallel_master_taskloop:
11809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11810 CaptureRegion = OMPD_parallel;
11811 break;
11812 case OMPD_parallel_master_taskloop_simd:
11813 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11814 NameModifier == OMPD_taskloop) {
11815 CaptureRegion = OMPD_parallel;
11816 break;
11817 }
11818 if (OpenMPVersion <= 45)
11819 break;
11820 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11821 CaptureRegion = OMPD_taskloop;
11822 break;
11823 case OMPD_parallel_for_simd:
11824 if (OpenMPVersion <= 45)
11825 break;
11826 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11827 CaptureRegion = OMPD_parallel;
11828 break;
11829 case OMPD_taskloop_simd:
11830 case OMPD_master_taskloop_simd:
11831 if (OpenMPVersion <= 45)
11832 break;
11833 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11834 CaptureRegion = OMPD_taskloop;
11835 break;
11836 case OMPD_distribute_parallel_for_simd:
11837 if (OpenMPVersion <= 45)
11838 break;
11839 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11840 CaptureRegion = OMPD_parallel;
11841 break;
11842 case OMPD_target_simd:
11843 if (OpenMPVersion >= 50 &&
11844 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11845 CaptureRegion = OMPD_target;
11846 break;
11847 case OMPD_teams_distribute_simd:
11848 case OMPD_target_teams_distribute_simd:
11849 if (OpenMPVersion >= 50 &&
11850 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11851 CaptureRegion = OMPD_teams;
11852 break;
11853 case OMPD_cancel:
11854 case OMPD_parallel:
11855 case OMPD_parallel_master:
11856 case OMPD_parallel_sections:
11857 case OMPD_parallel_for:
11858 case OMPD_target:
11859 case OMPD_target_teams:
11860 case OMPD_target_teams_distribute:
11861 case OMPD_distribute_parallel_for:
11862 case OMPD_task:
11863 case OMPD_taskloop:
11864 case OMPD_master_taskloop:
11865 case OMPD_target_data:
11866 case OMPD_simd:
11867 case OMPD_for_simd:
11868 case OMPD_distribute_simd:
11869 // Do not capture if-clause expressions.
11870 break;
11871 case OMPD_threadprivate:
11872 case OMPD_allocate:
11873 case OMPD_taskyield:
11874 case OMPD_barrier:
11875 case OMPD_taskwait:
11876 case OMPD_cancellation_point:
11877 case OMPD_flush:
11878 case OMPD_depobj:
11879 case OMPD_scan:
11880 case OMPD_declare_reduction:
11881 case OMPD_declare_mapper:
11882 case OMPD_declare_simd:
11883 case OMPD_declare_variant:
11884 case OMPD_begin_declare_variant:
11885 case OMPD_end_declare_variant:
11886 case OMPD_declare_target:
11887 case OMPD_end_declare_target:
11888 case OMPD_teams:
11889 case OMPD_for:
11890 case OMPD_sections:
11891 case OMPD_section:
11892 case OMPD_single:
11893 case OMPD_master:
11894 case OMPD_critical:
11895 case OMPD_taskgroup:
11896 case OMPD_distribute:
11897 case OMPD_ordered:
11898 case OMPD_atomic:
11899 case OMPD_teams_distribute:
11900 case OMPD_requires:
11901 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11901)
;
11902 case OMPD_unknown:
11903 default:
11904 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11904)
;
11905 }
11906 break;
11907 case OMPC_num_threads:
11908 switch (DKind) {
11909 case OMPD_target_parallel:
11910 case OMPD_target_parallel_for:
11911 case OMPD_target_parallel_for_simd:
11912 CaptureRegion = OMPD_target;
11913 break;
11914 case OMPD_teams_distribute_parallel_for:
11915 case OMPD_teams_distribute_parallel_for_simd:
11916 case OMPD_target_teams_distribute_parallel_for:
11917 case OMPD_target_teams_distribute_parallel_for_simd:
11918 CaptureRegion = OMPD_teams;
11919 break;
11920 case OMPD_parallel:
11921 case OMPD_parallel_master:
11922 case OMPD_parallel_sections:
11923 case OMPD_parallel_for:
11924 case OMPD_parallel_for_simd:
11925 case OMPD_distribute_parallel_for:
11926 case OMPD_distribute_parallel_for_simd:
11927 case OMPD_parallel_master_taskloop:
11928 case OMPD_parallel_master_taskloop_simd:
11929 // Do not capture num_threads-clause expressions.
11930 break;
11931 case OMPD_target_data:
11932 case OMPD_target_enter_data:
11933 case OMPD_target_exit_data:
11934 case OMPD_target_update:
11935 case OMPD_target:
11936 case OMPD_target_simd:
11937 case OMPD_target_teams:
11938 case OMPD_target_teams_distribute:
11939 case OMPD_target_teams_distribute_simd:
11940 case OMPD_cancel:
11941 case OMPD_task:
11942 case OMPD_taskloop:
11943 case OMPD_taskloop_simd:
11944 case OMPD_master_taskloop:
11945 case OMPD_master_taskloop_simd:
11946 case OMPD_threadprivate:
11947 case OMPD_allocate:
11948 case OMPD_taskyield:
11949 case OMPD_barrier:
11950 case OMPD_taskwait:
11951 case OMPD_cancellation_point:
11952 case OMPD_flush:
11953 case OMPD_depobj:
11954 case OMPD_scan:
11955 case OMPD_declare_reduction:
11956 case OMPD_declare_mapper:
11957 case OMPD_declare_simd:
11958 case OMPD_declare_variant:
11959 case OMPD_begin_declare_variant:
11960 case OMPD_end_declare_variant:
11961 case OMPD_declare_target:
11962 case OMPD_end_declare_target:
11963 case OMPD_teams:
11964 case OMPD_simd:
11965 case OMPD_for:
11966 case OMPD_for_simd:
11967 case OMPD_sections:
11968 case OMPD_section:
11969 case OMPD_single:
11970 case OMPD_master:
11971 case OMPD_critical:
11972 case OMPD_taskgroup:
11973 case OMPD_distribute:
11974 case OMPD_ordered:
11975 case OMPD_atomic:
11976 case OMPD_distribute_simd:
11977 case OMPD_teams_distribute:
11978 case OMPD_teams_distribute_simd:
11979 case OMPD_requires:
11980 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11980)
;
11981 case OMPD_unknown:
11982 default:
11983 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 11983)
;
11984 }
11985 break;
11986 case OMPC_num_teams:
11987 switch (DKind) {
11988 case OMPD_target_teams:
11989 case OMPD_target_teams_distribute:
11990 case OMPD_target_teams_distribute_simd:
11991 case OMPD_target_teams_distribute_parallel_for:
11992 case OMPD_target_teams_distribute_parallel_for_simd:
11993 CaptureRegion = OMPD_target;
11994 break;
11995 case OMPD_teams_distribute_parallel_for:
11996 case OMPD_teams_distribute_parallel_for_simd:
11997 case OMPD_teams:
11998 case OMPD_teams_distribute:
11999 case OMPD_teams_distribute_simd:
12000 // Do not capture num_teams-clause expressions.
12001 break;
12002 case OMPD_distribute_parallel_for:
12003 case OMPD_distribute_parallel_for_simd:
12004 case OMPD_task:
12005 case OMPD_taskloop:
12006 case OMPD_taskloop_simd:
12007 case OMPD_master_taskloop:
12008 case OMPD_master_taskloop_simd:
12009 case OMPD_parallel_master_taskloop:
12010 case OMPD_parallel_master_taskloop_simd:
12011 case OMPD_target_data:
12012 case OMPD_target_enter_data:
12013 case OMPD_target_exit_data:
12014 case OMPD_target_update:
12015 case OMPD_cancel:
12016 case OMPD_parallel:
12017 case OMPD_parallel_master:
12018 case OMPD_parallel_sections:
12019 case OMPD_parallel_for:
12020 case OMPD_parallel_for_simd:
12021 case OMPD_target:
12022 case OMPD_target_simd:
12023 case OMPD_target_parallel:
12024 case OMPD_target_parallel_for:
12025 case OMPD_target_parallel_for_simd:
12026 case OMPD_threadprivate:
12027 case OMPD_allocate:
12028 case OMPD_taskyield:
12029 case OMPD_barrier:
12030 case OMPD_taskwait:
12031 case OMPD_cancellation_point:
12032 case OMPD_flush:
12033 case OMPD_depobj:
12034 case OMPD_scan:
12035 case OMPD_declare_reduction:
12036 case OMPD_declare_mapper:
12037 case OMPD_declare_simd:
12038 case OMPD_declare_variant:
12039 case OMPD_begin_declare_variant:
12040 case OMPD_end_declare_variant:
12041 case OMPD_declare_target:
12042 case OMPD_end_declare_target:
12043 case OMPD_simd:
12044 case OMPD_for:
12045 case OMPD_for_simd:
12046 case OMPD_sections:
12047 case OMPD_section:
12048 case OMPD_single:
12049 case OMPD_master:
12050 case OMPD_critical:
12051 case OMPD_taskgroup:
12052 case OMPD_distribute:
12053 case OMPD_ordered:
12054 case OMPD_atomic:
12055 case OMPD_distribute_simd:
12056 case OMPD_requires:
12057 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12057)
;
12058 case OMPD_unknown:
12059 default:
12060 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12060)
;
12061 }
12062 break;
12063 case OMPC_thread_limit:
12064 switch (DKind) {
12065 case OMPD_target_teams:
12066 case OMPD_target_teams_distribute:
12067 case OMPD_target_teams_distribute_simd:
12068 case OMPD_target_teams_distribute_parallel_for:
12069 case OMPD_target_teams_distribute_parallel_for_simd:
12070 CaptureRegion = OMPD_target;
12071 break;
12072 case OMPD_teams_distribute_parallel_for:
12073 case OMPD_teams_distribute_parallel_for_simd:
12074 case OMPD_teams:
12075 case OMPD_teams_distribute:
12076 case OMPD_teams_distribute_simd:
12077 // Do not capture thread_limit-clause expressions.
12078 break;
12079 case OMPD_distribute_parallel_for:
12080 case OMPD_distribute_parallel_for_simd:
12081 case OMPD_task:
12082 case OMPD_taskloop:
12083 case OMPD_taskloop_simd:
12084 case OMPD_master_taskloop:
12085 case OMPD_master_taskloop_simd:
12086 case OMPD_parallel_master_taskloop:
12087 case OMPD_parallel_master_taskloop_simd:
12088 case OMPD_target_data:
12089 case OMPD_target_enter_data:
12090 case OMPD_target_exit_data:
12091 case OMPD_target_update:
12092 case OMPD_cancel:
12093 case OMPD_parallel:
12094 case OMPD_parallel_master:
12095 case OMPD_parallel_sections:
12096 case OMPD_parallel_for:
12097 case OMPD_parallel_for_simd:
12098 case OMPD_target:
12099 case OMPD_target_simd:
12100 case OMPD_target_parallel:
12101 case OMPD_target_parallel_for:
12102 case OMPD_target_parallel_for_simd:
12103 case OMPD_threadprivate:
12104 case OMPD_allocate:
12105 case OMPD_taskyield:
12106 case OMPD_barrier:
12107 case OMPD_taskwait:
12108 case OMPD_cancellation_point:
12109 case OMPD_flush:
12110 case OMPD_depobj:
12111 case OMPD_scan:
12112 case OMPD_declare_reduction:
12113 case OMPD_declare_mapper:
12114 case OMPD_declare_simd:
12115 case OMPD_declare_variant:
12116 case OMPD_begin_declare_variant:
12117 case OMPD_end_declare_variant:
12118 case OMPD_declare_target:
12119 case OMPD_end_declare_target:
12120 case OMPD_simd:
12121 case OMPD_for:
12122 case OMPD_for_simd:
12123 case OMPD_sections:
12124 case OMPD_section:
12125 case OMPD_single:
12126 case OMPD_master:
12127 case OMPD_critical:
12128 case OMPD_taskgroup:
12129 case OMPD_distribute:
12130 case OMPD_ordered:
12131 case OMPD_atomic:
12132 case OMPD_distribute_simd:
12133 case OMPD_requires:
12134 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12134)
;
12135 case OMPD_unknown:
12136 default:
12137 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12137)
;
12138 }
12139 break;
12140 case OMPC_schedule:
12141 switch (DKind) {
12142 case OMPD_parallel_for:
12143 case OMPD_parallel_for_simd:
12144 case OMPD_distribute_parallel_for:
12145 case OMPD_distribute_parallel_for_simd:
12146 case OMPD_teams_distribute_parallel_for:
12147 case OMPD_teams_distribute_parallel_for_simd:
12148 case OMPD_target_parallel_for:
12149 case OMPD_target_parallel_for_simd:
12150 case OMPD_target_teams_distribute_parallel_for:
12151 case OMPD_target_teams_distribute_parallel_for_simd:
12152 CaptureRegion = OMPD_parallel;
12153 break;
12154 case OMPD_for:
12155 case OMPD_for_simd:
12156 // Do not capture schedule-clause expressions.
12157 break;
12158 case OMPD_task:
12159 case OMPD_taskloop:
12160 case OMPD_taskloop_simd:
12161 case OMPD_master_taskloop:
12162 case OMPD_master_taskloop_simd:
12163 case OMPD_parallel_master_taskloop:
12164 case OMPD_parallel_master_taskloop_simd:
12165 case OMPD_target_data:
12166 case OMPD_target_enter_data:
12167 case OMPD_target_exit_data:
12168 case OMPD_target_update:
12169 case OMPD_teams:
12170 case OMPD_teams_distribute:
12171 case OMPD_teams_distribute_simd:
12172 case OMPD_target_teams_distribute:
12173 case OMPD_target_teams_distribute_simd:
12174 case OMPD_target:
12175 case OMPD_target_simd:
12176 case OMPD_target_parallel:
12177 case OMPD_cancel:
12178 case OMPD_parallel:
12179 case OMPD_parallel_master:
12180 case OMPD_parallel_sections:
12181 case OMPD_threadprivate:
12182 case OMPD_allocate:
12183 case OMPD_taskyield:
12184 case OMPD_barrier:
12185 case OMPD_taskwait:
12186 case OMPD_cancellation_point:
12187 case OMPD_flush:
12188 case OMPD_depobj:
12189 case OMPD_scan:
12190 case OMPD_declare_reduction:
12191 case OMPD_declare_mapper:
12192 case OMPD_declare_simd:
12193 case OMPD_declare_variant:
12194 case OMPD_begin_declare_variant:
12195 case OMPD_end_declare_variant:
12196 case OMPD_declare_target:
12197 case OMPD_end_declare_target:
12198 case OMPD_simd:
12199 case OMPD_sections:
12200 case OMPD_section:
12201 case OMPD_single:
12202 case OMPD_master:
12203 case OMPD_critical:
12204 case OMPD_taskgroup:
12205 case OMPD_distribute:
12206 case OMPD_ordered:
12207 case OMPD_atomic:
12208 case OMPD_distribute_simd:
12209 case OMPD_target_teams:
12210 case OMPD_requires:
12211 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12211)
;
12212 case OMPD_unknown:
12213 default:
12214 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12214)
;
12215 }
12216 break;
12217 case OMPC_dist_schedule:
12218 switch (DKind) {
12219 case OMPD_teams_distribute_parallel_for:
12220 case OMPD_teams_distribute_parallel_for_simd:
12221 case OMPD_teams_distribute:
12222 case OMPD_teams_distribute_simd:
12223 case OMPD_target_teams_distribute_parallel_for:
12224 case OMPD_target_teams_distribute_parallel_for_simd:
12225 case OMPD_target_teams_distribute:
12226 case OMPD_target_teams_distribute_simd:
12227 CaptureRegion = OMPD_teams;
12228 break;
12229 case OMPD_distribute_parallel_for:
12230 case OMPD_distribute_parallel_for_simd:
12231 case OMPD_distribute:
12232 case OMPD_distribute_simd:
12233 // Do not capture thread_limit-clause expressions.
12234 break;
12235 case OMPD_parallel_for:
12236 case OMPD_parallel_for_simd:
12237 case OMPD_target_parallel_for_simd:
12238 case OMPD_target_parallel_for:
12239 case OMPD_task:
12240 case OMPD_taskloop:
12241 case OMPD_taskloop_simd:
12242 case OMPD_master_taskloop:
12243 case OMPD_master_taskloop_simd:
12244 case OMPD_parallel_master_taskloop:
12245 case OMPD_parallel_master_taskloop_simd:
12246 case OMPD_target_data:
12247 case OMPD_target_enter_data:
12248 case OMPD_target_exit_data:
12249 case OMPD_target_update:
12250 case OMPD_teams:
12251 case OMPD_target:
12252 case OMPD_target_simd:
12253 case OMPD_target_parallel:
12254 case OMPD_cancel:
12255 case OMPD_parallel:
12256 case OMPD_parallel_master:
12257 case OMPD_parallel_sections:
12258 case OMPD_threadprivate:
12259 case OMPD_allocate:
12260 case OMPD_taskyield:
12261 case OMPD_barrier:
12262 case OMPD_taskwait:
12263 case OMPD_cancellation_point:
12264 case OMPD_flush:
12265 case OMPD_depobj:
12266 case OMPD_scan:
12267 case OMPD_declare_reduction:
12268 case OMPD_declare_mapper:
12269 case OMPD_declare_simd:
12270 case OMPD_declare_variant:
12271 case OMPD_begin_declare_variant:
12272 case OMPD_end_declare_variant:
12273 case OMPD_declare_target:
12274 case OMPD_end_declare_target:
12275 case OMPD_simd:
12276 case OMPD_for:
12277 case OMPD_for_simd:
12278 case OMPD_sections:
12279 case OMPD_section:
12280 case OMPD_single:
12281 case OMPD_master:
12282 case OMPD_critical:
12283 case OMPD_taskgroup:
12284 case OMPD_ordered:
12285 case OMPD_atomic:
12286 case OMPD_target_teams:
12287 case OMPD_requires:
12288 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12288)
;
12289 case OMPD_unknown:
12290 default:
12291 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12291)
;
12292 }
12293 break;
12294 case OMPC_device:
12295 switch (DKind) {
12296 case OMPD_target_update:
12297 case OMPD_target_enter_data:
12298 case OMPD_target_exit_data:
12299 case OMPD_target:
12300 case OMPD_target_simd:
12301 case OMPD_target_teams:
12302 case OMPD_target_parallel:
12303 case OMPD_target_teams_distribute:
12304 case OMPD_target_teams_distribute_simd:
12305 case OMPD_target_parallel_for:
12306 case OMPD_target_parallel_for_simd:
12307 case OMPD_target_teams_distribute_parallel_for:
12308 case OMPD_target_teams_distribute_parallel_for_simd:
12309 CaptureRegion = OMPD_task;
12310 break;
12311 case OMPD_target_data:
12312 // Do not capture device-clause expressions.
12313 break;
12314 case OMPD_teams_distribute_parallel_for:
12315 case OMPD_teams_distribute_parallel_for_simd:
12316 case OMPD_teams:
12317 case OMPD_teams_distribute:
12318 case OMPD_teams_distribute_simd:
12319 case OMPD_distribute_parallel_for:
12320 case OMPD_distribute_parallel_for_simd:
12321 case OMPD_task:
12322 case OMPD_taskloop:
12323 case OMPD_taskloop_simd:
12324 case OMPD_master_taskloop:
12325 case OMPD_master_taskloop_simd:
12326 case OMPD_parallel_master_taskloop:
12327 case OMPD_parallel_master_taskloop_simd:
12328 case OMPD_cancel:
12329 case OMPD_parallel:
12330 case OMPD_parallel_master:
12331 case OMPD_parallel_sections:
12332 case OMPD_parallel_for:
12333 case OMPD_parallel_for_simd:
12334 case OMPD_threadprivate:
12335 case OMPD_allocate:
12336 case OMPD_taskyield:
12337 case OMPD_barrier:
12338 case OMPD_taskwait:
12339 case OMPD_cancellation_point:
12340 case OMPD_flush:
12341 case OMPD_depobj:
12342 case OMPD_scan:
12343 case OMPD_declare_reduction:
12344 case OMPD_declare_mapper:
12345 case OMPD_declare_simd:
12346 case OMPD_declare_variant:
12347 case OMPD_begin_declare_variant:
12348 case OMPD_end_declare_variant:
12349 case OMPD_declare_target:
12350 case OMPD_end_declare_target:
12351 case OMPD_simd:
12352 case OMPD_for:
12353 case OMPD_for_simd:
12354 case OMPD_sections:
12355 case OMPD_section:
12356 case OMPD_single:
12357 case OMPD_master:
12358 case OMPD_critical:
12359 case OMPD_taskgroup:
12360 case OMPD_distribute:
12361 case OMPD_ordered:
12362 case OMPD_atomic:
12363 case OMPD_distribute_simd:
12364 case OMPD_requires:
12365 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12365)
;
12366 case OMPD_unknown:
12367 default:
12368 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12368)
;
12369 }
12370 break;
12371 case OMPC_grainsize:
12372 case OMPC_num_tasks:
12373 case OMPC_final:
12374 case OMPC_priority:
12375 switch (DKind) {
12376 case OMPD_task:
12377 case OMPD_taskloop:
12378 case OMPD_taskloop_simd:
12379 case OMPD_master_taskloop:
12380 case OMPD_master_taskloop_simd:
12381 break;
12382 case OMPD_parallel_master_taskloop:
12383 case OMPD_parallel_master_taskloop_simd:
12384 CaptureRegion = OMPD_parallel;
12385 break;
12386 case OMPD_target_update:
12387 case OMPD_target_enter_data:
12388 case OMPD_target_exit_data:
12389 case OMPD_target:
12390 case OMPD_target_simd:
12391 case OMPD_target_teams:
12392 case OMPD_target_parallel:
12393 case OMPD_target_teams_distribute:
12394 case OMPD_target_teams_distribute_simd:
12395 case OMPD_target_parallel_for:
12396 case OMPD_target_parallel_for_simd:
12397 case OMPD_target_teams_distribute_parallel_for:
12398 case OMPD_target_teams_distribute_parallel_for_simd:
12399 case OMPD_target_data:
12400 case OMPD_teams_distribute_parallel_for:
12401 case OMPD_teams_distribute_parallel_for_simd:
12402 case OMPD_teams:
12403 case OMPD_teams_distribute:
12404 case OMPD_teams_distribute_simd:
12405 case OMPD_distribute_parallel_for:
12406 case OMPD_distribute_parallel_for_simd:
12407 case OMPD_cancel:
12408 case OMPD_parallel:
12409 case OMPD_parallel_master:
12410 case OMPD_parallel_sections:
12411 case OMPD_parallel_for:
12412 case OMPD_parallel_for_simd:
12413 case OMPD_threadprivate:
12414 case OMPD_allocate:
12415 case OMPD_taskyield:
12416 case OMPD_barrier:
12417 case OMPD_taskwait:
12418 case OMPD_cancellation_point:
12419 case OMPD_flush:
12420 case OMPD_depobj:
12421 case OMPD_scan:
12422 case OMPD_declare_reduction:
12423 case OMPD_declare_mapper:
12424 case OMPD_declare_simd:
12425 case OMPD_declare_variant:
12426 case OMPD_begin_declare_variant:
12427 case OMPD_end_declare_variant:
12428 case OMPD_declare_target:
12429 case OMPD_end_declare_target:
12430 case OMPD_simd:
12431 case OMPD_for:
12432 case OMPD_for_simd:
12433 case OMPD_sections:
12434 case OMPD_section:
12435 case OMPD_single:
12436 case OMPD_master:
12437 case OMPD_critical:
12438 case OMPD_taskgroup:
12439 case OMPD_distribute:
12440 case OMPD_ordered:
12441 case OMPD_atomic:
12442 case OMPD_distribute_simd:
12443 case OMPD_requires:
12444 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12444)
;
12445 case OMPD_unknown:
12446 default:
12447 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12447)
;
12448 }
12449 break;
12450 case OMPC_firstprivate:
12451 case OMPC_lastprivate:
12452 case OMPC_reduction:
12453 case OMPC_task_reduction:
12454 case OMPC_in_reduction:
12455 case OMPC_linear:
12456 case OMPC_default:
12457 case OMPC_proc_bind:
12458 case OMPC_safelen:
12459 case OMPC_simdlen:
12460 case OMPC_allocator:
12461 case OMPC_collapse:
12462 case OMPC_private:
12463 case OMPC_shared:
12464 case OMPC_aligned:
12465 case OMPC_copyin:
12466 case OMPC_copyprivate:
12467 case OMPC_ordered:
12468 case OMPC_nowait:
12469 case OMPC_untied:
12470 case OMPC_mergeable:
12471 case OMPC_threadprivate:
12472 case OMPC_allocate:
12473 case OMPC_flush:
12474 case OMPC_depobj:
12475 case OMPC_read:
12476 case OMPC_write:
12477 case OMPC_update:
12478 case OMPC_capture:
12479 case OMPC_seq_cst:
12480 case OMPC_acq_rel:
12481 case OMPC_acquire:
12482 case OMPC_release:
12483 case OMPC_relaxed:
12484 case OMPC_depend:
12485 case OMPC_threads:
12486 case OMPC_simd:
12487 case OMPC_map:
12488 case OMPC_nogroup:
12489 case OMPC_hint:
12490 case OMPC_defaultmap:
12491 case OMPC_unknown:
12492 case OMPC_uniform:
12493 case OMPC_to:
12494 case OMPC_from:
12495 case OMPC_use_device_ptr:
12496 case OMPC_use_device_addr:
12497 case OMPC_is_device_ptr:
12498 case OMPC_unified_address:
12499 case OMPC_unified_shared_memory:
12500 case OMPC_reverse_offload:
12501 case OMPC_dynamic_allocators:
12502 case OMPC_atomic_default_mem_order:
12503 case OMPC_device_type:
12504 case OMPC_match:
12505 case OMPC_nontemporal:
12506 case OMPC_order:
12507 case OMPC_destroy:
12508 case OMPC_detach:
12509 case OMPC_inclusive:
12510 case OMPC_exclusive:
12511 case OMPC_uses_allocators:
12512 case OMPC_affinity:
12513 default:
12514 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12514)
;
12515 }
12516 return CaptureRegion;
12517}
12518
12519OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12520 Expr *Condition, SourceLocation StartLoc,
12521 SourceLocation LParenLoc,
12522 SourceLocation NameModifierLoc,
12523 SourceLocation ColonLoc,
12524 SourceLocation EndLoc) {
12525 Expr *ValExpr = Condition;
12526 Stmt *HelperValStmt = nullptr;
12527 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12528 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12529 !Condition->isInstantiationDependent() &&
12530 !Condition->containsUnexpandedParameterPack()) {
12531 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12532 if (Val.isInvalid())
12533 return nullptr;
12534
12535 ValExpr = Val.get();
12536
12537 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12538 CaptureRegion = getOpenMPCaptureRegionForClause(
12539 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12540 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12541 ValExpr = MakeFullExpr(ValExpr).get();
12542 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12543 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12544 HelperValStmt = buildPreInits(Context, Captures);
12545 }
12546 }
12547
12548 return new (Context)
12549 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12550 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12551}
12552
12553OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12554 SourceLocation StartLoc,
12555 SourceLocation LParenLoc,
12556 SourceLocation EndLoc) {
12557 Expr *ValExpr = Condition;
12558 Stmt *HelperValStmt = nullptr;
12559 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12560 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12561 !Condition->isInstantiationDependent() &&
12562 !Condition->containsUnexpandedParameterPack()) {
12563 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12564 if (Val.isInvalid())
12565 return nullptr;
12566
12567 ValExpr = MakeFullExpr(Val.get()).get();
12568
12569 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12570 CaptureRegion =
12571 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12572 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12573 ValExpr = MakeFullExpr(ValExpr).get();
12574 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12575 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12576 HelperValStmt = buildPreInits(Context, Captures);
12577 }
12578 }
12579
12580 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12581 StartLoc, LParenLoc, EndLoc);
12582}
12583
12584ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12585 Expr *Op) {
12586 if (!Op)
12587 return ExprError();
12588
12589 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12590 public:
12591 IntConvertDiagnoser()
12592 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12593 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12594 QualType T) override {
12595 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12596 }
12597 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12598 QualType T) override {
12599 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12600 }
12601 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12602 QualType T,
12603 QualType ConvTy) override {
12604 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12605 }
12606 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12607 QualType ConvTy) override {
12608 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12609 << ConvTy->isEnumeralType() << ConvTy;
12610 }
12611 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12612 QualType T) override {
12613 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12614 }
12615 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12616 QualType ConvTy) override {
12617 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12618 << ConvTy->isEnumeralType() << ConvTy;
12619 }
12620 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12621 QualType) override {
12622 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12622)
;
12623 }
12624 } ConvertDiagnoser;
12625 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12626}
12627
12628static bool
12629isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12630 bool StrictlyPositive, bool BuildCapture = false,
12631 OpenMPDirectiveKind DKind = OMPD_unknown,
12632 OpenMPDirectiveKind *CaptureRegion = nullptr,
12633 Stmt **HelperValStmt = nullptr) {
12634 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12635 !ValExpr->isInstantiationDependent()) {
12636 SourceLocation Loc = ValExpr->getExprLoc();
12637 ExprResult Value =
12638 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12639 if (Value.isInvalid())
12640 return false;
12641
12642 ValExpr = Value.get();
12643 // The expression must evaluate to a non-negative integer value.
12644 if (Optional<llvm::APSInt> Result =
12645 ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
12646 if (Result->isSigned() &&
12647 !((!StrictlyPositive && Result->isNonNegative()) ||
12648 (StrictlyPositive && Result->isStrictlyPositive()))) {
12649 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12650 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12651 << ValExpr->getSourceRange();
12652 return false;
12653 }
12654 }
12655 if (!BuildCapture)
12656 return true;
12657 *CaptureRegion =
12658 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12659 if (*CaptureRegion != OMPD_unknown &&
12660 !SemaRef.CurContext->isDependentContext()) {
12661 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12662 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12663 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12664 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12665 }
12666 }
12667 return true;
12668}
12669
12670OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12671 SourceLocation StartLoc,
12672 SourceLocation LParenLoc,
12673 SourceLocation EndLoc) {
12674 Expr *ValExpr = NumThreads;
12675 Stmt *HelperValStmt = nullptr;
12676
12677 // OpenMP [2.5, Restrictions]
12678 // The num_threads expression must evaluate to a positive integer value.
12679 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12680 /*StrictlyPositive=*/true))
12681 return nullptr;
12682
12683 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12684 OpenMPDirectiveKind CaptureRegion =
12685 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12686 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12687 ValExpr = MakeFullExpr(ValExpr).get();
12688 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12689 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12690 HelperValStmt = buildPreInits(Context, Captures);
12691 }
12692
12693 return new (Context) OMPNumThreadsClause(
12694 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12695}
12696
12697ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12698 OpenMPClauseKind CKind,
12699 bool StrictlyPositive) {
12700 if (!E)
12701 return ExprError();
12702 if (E->isValueDependent() || E->isTypeDependent() ||
12703 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12704 return E;
12705 llvm::APSInt Result;
12706 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
12707 if (ICE.isInvalid())
12708 return ExprError();
12709 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12710 (!StrictlyPositive && !Result.isNonNegative())) {
12711 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12712 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12713 << E->getSourceRange();
12714 return ExprError();
12715 }
12716 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12717 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12718 << E->getSourceRange();
12719 return ExprError();
12720 }
12721 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
12722 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12723 else if (CKind == OMPC_ordered)
12724 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
12725 return ICE;
12726}
12727
12728OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12729 SourceLocation LParenLoc,
12730 SourceLocation EndLoc) {
12731 // OpenMP [2.8.1, simd construct, Description]
12732 // The parameter of the safelen clause must be a constant
12733 // positive integer expression.
12734 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12735 if (Safelen.isInvalid())
12736 return nullptr;
12737 return new (Context)
12738 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12739}
12740
12741OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12742 SourceLocation LParenLoc,
12743 SourceLocation EndLoc) {
12744 // OpenMP [2.8.1, simd construct, Description]
12745 // The parameter of the simdlen clause must be a constant
12746 // positive integer expression.
12747 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12748 if (Simdlen.isInvalid())
12749 return nullptr;
12750 return new (Context)
12751 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12752}
12753
12754/// Tries to find omp_allocator_handle_t type.
12755static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12756 DSAStackTy *Stack) {
12757 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12758 if (!OMPAllocatorHandleT.isNull())
12759 return true;
12760 // Build the predefined allocator expressions.
12761 bool ErrorFound = false;
12762 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12763 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12764 StringRef Allocator =
12765 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12766 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12767 auto *VD = dyn_cast_or_null<ValueDecl>(
12768 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12769 if (!VD) {
12770 ErrorFound = true;
12771 break;
12772 }
12773 QualType AllocatorType =
12774 VD->getType().getNonLValueExprType(S.getASTContext());
12775 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12776 if (!Res.isUsable()) {
12777 ErrorFound = true;
12778 break;
12779 }
12780 if (OMPAllocatorHandleT.isNull())
12781 OMPAllocatorHandleT = AllocatorType;
12782 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12783 ErrorFound = true;
12784 break;
12785 }
12786 Stack->setAllocator(AllocatorKind, Res.get());
12787 }
12788 if (ErrorFound) {
12789 S.Diag(Loc, diag::err_omp_implied_type_not_found)
12790 << "omp_allocator_handle_t";
12791 return false;
12792 }
12793 OMPAllocatorHandleT.addConst();
12794 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12795 return true;
12796}
12797
12798OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12799 SourceLocation LParenLoc,
12800 SourceLocation EndLoc) {
12801 // OpenMP [2.11.3, allocate Directive, Description]
12802 // allocator is an expression of omp_allocator_handle_t type.
12803 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12804 return nullptr;
12805
12806 ExprResult Allocator = DefaultLvalueConversion(A);
12807 if (Allocator.isInvalid())
12808 return nullptr;
12809 Allocator = PerformImplicitConversion(Allocator.get(),
12810 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
12811 Sema::AA_Initializing,
12812 /*AllowExplicit=*/true);
12813 if (Allocator.isInvalid())
12814 return nullptr;
12815 return new (Context)
12816 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12817}
12818
12819OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12820 SourceLocation StartLoc,
12821 SourceLocation LParenLoc,
12822 SourceLocation EndLoc) {
12823 // OpenMP [2.7.1, loop construct, Description]
12824 // OpenMP [2.8.1, simd construct, Description]
12825 // OpenMP [2.9.6, distribute construct, Description]
12826 // The parameter of the collapse clause must be a constant
12827 // positive integer expression.
12828 ExprResult NumForLoopsResult =
12829 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12830 if (NumForLoopsResult.isInvalid())
12831 return nullptr;
12832 return new (Context)
12833 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12834}
12835
12836OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12837 SourceLocation EndLoc,
12838 SourceLocation LParenLoc,
12839 Expr *NumForLoops) {
12840 // OpenMP [2.7.1, loop construct, Description]
12841 // OpenMP [2.8.1, simd construct, Description]
12842 // OpenMP [2.9.6, distribute construct, Description]
12843 // The parameter of the ordered clause must be a constant
12844 // positive integer expression if any.
12845 if (NumForLoops && LParenLoc.isValid()) {
12846 ExprResult NumForLoopsResult =
12847 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12848 if (NumForLoopsResult.isInvalid())
12849 return nullptr;
12850 NumForLoops = NumForLoopsResult.get();
12851 } else {
12852 NumForLoops = nullptr;
12853 }
12854 auto *Clause = OMPOrderedClause::Create(
12855 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
12856 StartLoc, LParenLoc, EndLoc);
12857 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12858 return Clause;
12859}
12860
12861OMPClause *Sema::ActOnOpenMPSimpleClause(
12862 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12863 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12864 OMPClause *Res = nullptr;
12865 switch (Kind) {
12866 case OMPC_default:
12867 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12868 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12869 break;
12870 case OMPC_proc_bind:
12871 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12872 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12873 break;
12874 case OMPC_atomic_default_mem_order:
12875 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12876 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12877 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12878 break;
12879 case OMPC_order:
12880 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
12881 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12882 break;
12883 case OMPC_update:
12884 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
12885 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12886 break;
12887 case OMPC_if:
12888 case OMPC_final:
12889 case OMPC_num_threads:
12890 case OMPC_safelen:
12891 case OMPC_simdlen:
12892 case OMPC_allocator:
12893 case OMPC_collapse:
12894 case OMPC_schedule:
12895 case OMPC_private:
12896 case OMPC_firstprivate:
12897 case OMPC_lastprivate:
12898 case OMPC_shared:
12899 case OMPC_reduction:
12900 case OMPC_task_reduction:
12901 case OMPC_in_reduction:
12902 case OMPC_linear:
12903 case OMPC_aligned:
12904 case OMPC_copyin:
12905 case OMPC_copyprivate:
12906 case OMPC_ordered:
12907 case OMPC_nowait:
12908 case OMPC_untied:
12909 case OMPC_mergeable:
12910 case OMPC_threadprivate:
12911 case OMPC_allocate:
12912 case OMPC_flush:
12913 case OMPC_depobj:
12914 case OMPC_read:
12915 case OMPC_write:
12916 case OMPC_capture:
12917 case OMPC_seq_cst:
12918 case OMPC_acq_rel:
12919 case OMPC_acquire:
12920 case OMPC_release:
12921 case OMPC_relaxed:
12922 case OMPC_depend:
12923 case OMPC_device:
12924 case OMPC_threads:
12925 case OMPC_simd:
12926 case OMPC_map:
12927 case OMPC_num_teams:
12928 case OMPC_thread_limit:
12929 case OMPC_priority:
12930 case OMPC_grainsize:
12931 case OMPC_nogroup:
12932 case OMPC_num_tasks:
12933 case OMPC_hint:
12934 case OMPC_dist_schedule:
12935 case OMPC_defaultmap:
12936 case OMPC_unknown:
12937 case OMPC_uniform:
12938 case OMPC_to:
12939 case OMPC_from:
12940 case OMPC_use_device_ptr:
12941 case OMPC_use_device_addr:
12942 case OMPC_is_device_ptr:
12943 case OMPC_unified_address:
12944 case OMPC_unified_shared_memory:
12945 case OMPC_reverse_offload:
12946 case OMPC_dynamic_allocators:
12947 case OMPC_device_type:
12948 case OMPC_match:
12949 case OMPC_nontemporal:
12950 case OMPC_destroy:
12951 case OMPC_detach:
12952 case OMPC_inclusive:
12953 case OMPC_exclusive:
12954 case OMPC_uses_allocators:
12955 case OMPC_affinity:
12956 default:
12957 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 12957)
;
12958 }
12959 return Res;
12960}
12961
12962static std::string
12963getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
12964 ArrayRef<unsigned> Exclude = llvm::None) {
12965 SmallString<256> Buffer;
12966 llvm::raw_svector_ostream Out(Buffer);
12967 unsigned Skipped = Exclude.size();
12968 auto S = Exclude.begin(), E = Exclude.end();
12969 for (unsigned I = First; I < Last; ++I) {
12970 if (std::find(S, E, I) != E) {
12971 --Skipped;
12972 continue;
12973 }
12974 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
12975 if (I + Skipped + 2 == Last)
12976 Out << " or ";
12977 else if (I + Skipped + 1 != Last)
12978 Out << ", ";
12979 }
12980 return std::string(Out.str());
12981}
12982
12983OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
12984 SourceLocation KindKwLoc,
12985 SourceLocation StartLoc,
12986 SourceLocation LParenLoc,
12987 SourceLocation EndLoc) {
12988 if (Kind == OMP_DEFAULT_unknown) {
12989 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12990 << getListOfPossibleValues(OMPC_default, /*First=*/0,
12991 /*Last=*/unsigned(OMP_DEFAULT_unknown))
12992 << getOpenMPClauseName(OMPC_default);
12993 return nullptr;
12994 }
12995
12996 switch (Kind) {
12997 case OMP_DEFAULT_none:
12998 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
12999 break;
13000 case OMP_DEFAULT_shared:
13001 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
13002 break;
13003 case OMP_DEFAULT_firstprivate:
13004 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAFirstPrivate(KindKwLoc);
13005 break;
13006 default:
13007 llvm_unreachable("DSA unexpected in OpenMP default clause")::llvm::llvm_unreachable_internal("DSA unexpected in OpenMP default clause"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13007)
;
13008 }
13009
13010 return new (Context)
13011 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13012}
13013
13014OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
13015 SourceLocation KindKwLoc,
13016 SourceLocation StartLoc,
13017 SourceLocation LParenLoc,
13018 SourceLocation EndLoc) {
13019 if (Kind == OMP_PROC_BIND_unknown) {
13020 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13021 << getListOfPossibleValues(OMPC_proc_bind,
13022 /*First=*/unsigned(OMP_PROC_BIND_master),
13023 /*Last=*/5)
13024 << getOpenMPClauseName(OMPC_proc_bind);
13025 return nullptr;
13026 }
13027 return new (Context)
13028 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13029}
13030
13031OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13032 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13033 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13034 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13035 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13036 << getListOfPossibleValues(
13037 OMPC_atomic_default_mem_order, /*First=*/0,
13038 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13039 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13040 return nullptr;
13041 }
13042 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13043 LParenLoc, EndLoc);
13044}
13045
13046OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13047 SourceLocation KindKwLoc,
13048 SourceLocation StartLoc,
13049 SourceLocation LParenLoc,
13050 SourceLocation EndLoc) {
13051 if (Kind == OMPC_ORDER_unknown) {
13052 static_assert(OMPC_ORDER_unknown > 0,
13053 "OMPC_ORDER_unknown not greater than 0");
13054 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13055 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13056 /*Last=*/OMPC_ORDER_unknown)
13057 << getOpenMPClauseName(OMPC_order);
13058 return nullptr;
13059 }
13060 return new (Context)
13061 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13062}
13063
13064OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13065 SourceLocation KindKwLoc,
13066 SourceLocation StartLoc,
13067 SourceLocation LParenLoc,
13068 SourceLocation EndLoc) {
13069 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13070 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13071 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13072 OMPC_DEPEND_depobj};
13073 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13074 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13075 /*Last=*/OMPC_DEPEND_unknown, Except)
13076 << getOpenMPClauseName(OMPC_update);
13077 return nullptr;
13078 }
13079 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13080 EndLoc);
13081}
13082
13083OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13084 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13085 SourceLocation StartLoc, SourceLocation LParenLoc,
13086 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13087 SourceLocation EndLoc) {
13088 OMPClause *Res = nullptr;
13089 switch (Kind) {
13090 case OMPC_schedule:
13091 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13092 assert(Argument.size() == NumberOfElements &&((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13093, __PRETTY_FUNCTION__))
13093 ArgumentLoc.size() == NumberOfElements)((Argument.size() == NumberOfElements && ArgumentLoc.
size() == NumberOfElements) ? static_cast<void> (0) : __assert_fail
("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13093, __PRETTY_FUNCTION__))
;
13094 Res = ActOnOpenMPScheduleClause(
13095 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13096 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13097 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13098 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13099 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13100 break;
13101 case OMPC_if:
13102 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13102, __PRETTY_FUNCTION__))
;
13103 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13104 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13105 DelimLoc, EndLoc);
13106 break;
13107 case OMPC_dist_schedule:
13108 Res = ActOnOpenMPDistScheduleClause(
13109 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13110 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13111 break;
13112 case OMPC_defaultmap:
13113 enum { Modifier, DefaultmapKind };
13114 Res = ActOnOpenMPDefaultmapClause(
13115 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13116 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13117 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13118 EndLoc);
13119 break;
13120 case OMPC_device:
13121 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)((Argument.size() == 1 && ArgumentLoc.size() == 1) ? static_cast
<void> (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13121, __PRETTY_FUNCTION__))
;
13122 Res = ActOnOpenMPDeviceClause(
13123 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13124 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13125 break;
13126 case OMPC_final:
13127 case OMPC_num_threads:
13128 case OMPC_safelen:
13129 case OMPC_simdlen:
13130 case OMPC_allocator:
13131 case OMPC_collapse:
13132 case OMPC_default:
13133 case OMPC_proc_bind:
13134 case OMPC_private:
13135 case OMPC_firstprivate:
13136 case OMPC_lastprivate:
13137 case OMPC_shared:
13138 case OMPC_reduction:
13139 case OMPC_task_reduction:
13140 case OMPC_in_reduction:
13141 case OMPC_linear:
13142 case OMPC_aligned:
13143 case OMPC_copyin:
13144 case OMPC_copyprivate:
13145 case OMPC_ordered:
13146 case OMPC_nowait:
13147 case OMPC_untied:
13148 case OMPC_mergeable:
13149 case OMPC_threadprivate:
13150 case OMPC_allocate:
13151 case OMPC_flush:
13152 case OMPC_depobj:
13153 case OMPC_read:
13154 case OMPC_write:
13155 case OMPC_update:
13156 case OMPC_capture:
13157 case OMPC_seq_cst:
13158 case OMPC_acq_rel:
13159 case OMPC_acquire:
13160 case OMPC_release:
13161 case OMPC_relaxed:
13162 case OMPC_depend:
13163 case OMPC_threads:
13164 case OMPC_simd:
13165 case OMPC_map:
13166 case OMPC_num_teams:
13167 case OMPC_thread_limit:
13168 case OMPC_priority:
13169 case OMPC_grainsize:
13170 case OMPC_nogroup:
13171 case OMPC_num_tasks:
13172 case OMPC_hint:
13173 case OMPC_unknown:
13174 case OMPC_uniform:
13175 case OMPC_to:
13176 case OMPC_from:
13177 case OMPC_use_device_ptr:
13178 case OMPC_use_device_addr:
13179 case OMPC_is_device_ptr:
13180 case OMPC_unified_address:
13181 case OMPC_unified_shared_memory:
13182 case OMPC_reverse_offload:
13183 case OMPC_dynamic_allocators:
13184 case OMPC_atomic_default_mem_order:
13185 case OMPC_device_type:
13186 case OMPC_match:
13187 case OMPC_nontemporal:
13188 case OMPC_order:
13189 case OMPC_destroy:
13190 case OMPC_detach:
13191 case OMPC_inclusive:
13192 case OMPC_exclusive:
13193 case OMPC_uses_allocators:
13194 case OMPC_affinity:
13195 default:
13196 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13196)
;
13197 }
13198 return Res;
13199}
13200
13201static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13202 OpenMPScheduleClauseModifier M2,
13203 SourceLocation M1Loc, SourceLocation M2Loc) {
13204 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13205 SmallVector<unsigned, 2> Excluded;
13206 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13207 Excluded.push_back(M2);
13208 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13209 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13210 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13211 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13212 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13213 << getListOfPossibleValues(OMPC_schedule,
13214 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13215 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13216 Excluded)
13217 << getOpenMPClauseName(OMPC_schedule);
13218 return true;
13219 }
13220 return false;
13221}
13222
13223OMPClause *Sema::ActOnOpenMPScheduleClause(
13224 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13225 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13226 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13227 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13228 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13229 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13230 return nullptr;
13231 // OpenMP, 2.7.1, Loop Construct, Restrictions
13232 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13233 // but not both.
13234 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13235 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13236 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13237 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13238 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13239 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13240 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13241 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13242 return nullptr;
13243 }
13244 if (Kind == OMPC_SCHEDULE_unknown) {
13245 std::string Values;
13246 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13247 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13248 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13249 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13250 Exclude);
13251 } else {
13252 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13253 /*Last=*/OMPC_SCHEDULE_unknown);
13254 }
13255 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13256 << Values << getOpenMPClauseName(OMPC_schedule);
13257 return nullptr;
13258 }
13259 // OpenMP, 2.7.1, Loop Construct, Restrictions
13260 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13261 // schedule(guided).
13262 // OpenMP 5.0 does not have this restriction.
13263 if (LangOpts.OpenMP < 50 &&
13264 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13265 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13266 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13267 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13268 diag::err_omp_schedule_nonmonotonic_static);
13269 return nullptr;
13270 }
13271 Expr *ValExpr = ChunkSize;
13272 Stmt *HelperValStmt = nullptr;
13273 if (ChunkSize) {
13274 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13275 !ChunkSize->isInstantiationDependent() &&
13276 !ChunkSize->containsUnexpandedParameterPack()) {
13277 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13278 ExprResult Val =
13279 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13280 if (Val.isInvalid())
13281 return nullptr;
13282
13283 ValExpr = Val.get();
13284
13285 // OpenMP [2.7.1, Restrictions]
13286 // chunk_size must be a loop invariant integer expression with a positive
13287 // value.
13288 if (Optional<llvm::APSInt> Result =
13289 ValExpr->getIntegerConstantExpr(Context)) {
13290 if (Result->isSigned() && !Result->isStrictlyPositive()) {
13291 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13292 << "schedule" << 1 << ChunkSize->getSourceRange();
13293 return nullptr;
13294 }
13295 } else if (getOpenMPCaptureRegionForClause(
13296 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
13297 LangOpts.OpenMP) != OMPD_unknown &&
13298 !CurContext->isDependentContext()) {
13299 ValExpr = MakeFullExpr(ValExpr).get();
13300 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13301 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13302 HelperValStmt = buildPreInits(Context, Captures);
13303 }
13304 }
13305 }
13306
13307 return new (Context)
13308 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13309 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13310}
13311
13312OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13313 SourceLocation StartLoc,
13314 SourceLocation EndLoc) {
13315 OMPClause *Res = nullptr;
13316 switch (Kind) {
13317 case OMPC_ordered:
13318 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13319 break;
13320 case OMPC_nowait:
13321 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13322 break;
13323 case OMPC_untied:
13324 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13325 break;
13326 case OMPC_mergeable:
13327 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13328 break;
13329 case OMPC_read:
13330 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13331 break;
13332 case OMPC_write:
13333 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13334 break;
13335 case OMPC_update:
13336 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13337 break;
13338 case OMPC_capture:
13339 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13340 break;
13341 case OMPC_seq_cst:
13342 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13343 break;
13344 case OMPC_acq_rel:
13345 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13346 break;
13347 case OMPC_acquire:
13348 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13349 break;
13350 case OMPC_release:
13351 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13352 break;
13353 case OMPC_relaxed:
13354 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13355 break;
13356 case OMPC_threads:
13357 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13358 break;
13359 case OMPC_simd:
13360 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13361 break;
13362 case OMPC_nogroup:
13363 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13364 break;
13365 case OMPC_unified_address:
13366 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13367 break;
13368 case OMPC_unified_shared_memory:
13369 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13370 break;
13371 case OMPC_reverse_offload:
13372 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13373 break;
13374 case OMPC_dynamic_allocators:
13375 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13376 break;
13377 case OMPC_destroy:
13378 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13379 break;
13380 case OMPC_if:
13381 case OMPC_final:
13382 case OMPC_num_threads:
13383 case OMPC_safelen:
13384 case OMPC_simdlen:
13385 case OMPC_allocator:
13386 case OMPC_collapse:
13387 case OMPC_schedule:
13388 case OMPC_private:
13389 case OMPC_firstprivate:
13390 case OMPC_lastprivate:
13391 case OMPC_shared:
13392 case OMPC_reduction:
13393 case OMPC_task_reduction:
13394 case OMPC_in_reduction:
13395 case OMPC_linear:
13396 case OMPC_aligned:
13397 case OMPC_copyin:
13398 case OMPC_copyprivate:
13399 case OMPC_default:
13400 case OMPC_proc_bind:
13401 case OMPC_threadprivate:
13402 case OMPC_allocate:
13403 case OMPC_flush:
13404 case OMPC_depobj:
13405 case OMPC_depend:
13406 case OMPC_device:
13407 case OMPC_map:
13408 case OMPC_num_teams:
13409 case OMPC_thread_limit:
13410 case OMPC_priority:
13411 case OMPC_grainsize:
13412 case OMPC_num_tasks:
13413 case OMPC_hint:
13414 case OMPC_dist_schedule:
13415 case OMPC_defaultmap:
13416 case OMPC_unknown:
13417 case OMPC_uniform:
13418 case OMPC_to:
13419 case OMPC_from:
13420 case OMPC_use_device_ptr:
13421 case OMPC_use_device_addr:
13422 case OMPC_is_device_ptr:
13423 case OMPC_atomic_default_mem_order:
13424 case OMPC_device_type:
13425 case OMPC_match:
13426 case OMPC_nontemporal:
13427 case OMPC_order:
13428 case OMPC_detach:
13429 case OMPC_inclusive:
13430 case OMPC_exclusive:
13431 case OMPC_uses_allocators:
13432 case OMPC_affinity:
13433 default:
13434 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13434)
;
13435 }
13436 return Res;
13437}
13438
13439OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13440 SourceLocation EndLoc) {
13441 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
13442 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13443}
13444
13445OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13446 SourceLocation EndLoc) {
13447 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13448}
13449
13450OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13451 SourceLocation EndLoc) {
13452 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13453}
13454
13455OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13456 SourceLocation EndLoc) {
13457 return new (Context) OMPReadClause(StartLoc, EndLoc);
13458}
13459
13460OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13461 SourceLocation EndLoc) {
13462 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13463}
13464
13465OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13466 SourceLocation EndLoc) {
13467 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13468}
13469
13470OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13471 SourceLocation EndLoc) {
13472 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13473}
13474
13475OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13476 SourceLocation EndLoc) {
13477 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13478}
13479
13480OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13481 SourceLocation EndLoc) {
13482 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13483}
13484
13485OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13486 SourceLocation EndLoc) {
13487 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13488}
13489
13490OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13491 SourceLocation EndLoc) {
13492 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13493}
13494
13495OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13496 SourceLocation EndLoc) {
13497 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13498}
13499
13500OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13501 SourceLocation EndLoc) {
13502 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13503}
13504
13505OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13506 SourceLocation EndLoc) {
13507 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13508}
13509
13510OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13511 SourceLocation EndLoc) {
13512 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13513}
13514
13515OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13516 SourceLocation EndLoc) {
13517 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13518}
13519
13520OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13521 SourceLocation EndLoc) {
13522 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13523}
13524
13525OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13526 SourceLocation EndLoc) {
13527 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13528}
13529
13530OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13531 SourceLocation EndLoc) {
13532 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13533}
13534
13535OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13536 SourceLocation EndLoc) {
13537 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13538}
13539
13540OMPClause *Sema::ActOnOpenMPVarListClause(
13541 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13542 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13543 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13544 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13545 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13546 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13547 SourceLocation ExtraModifierLoc,
13548 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
13549 ArrayRef<SourceLocation> MotionModifiersLoc) {
13550 SourceLocation StartLoc = Locs.StartLoc;
13551 SourceLocation LParenLoc = Locs.LParenLoc;
13552 SourceLocation EndLoc = Locs.EndLoc;
13553 OMPClause *Res = nullptr;
13554 switch (Kind) {
13555 case OMPC_private:
13556 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13557 break;
13558 case OMPC_firstprivate:
13559 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13560 break;
13561 case OMPC_lastprivate:
13562 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13563, __PRETTY_FUNCTION__))
13563 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13563, __PRETTY_FUNCTION__))
;
13564 Res = ActOnOpenMPLastprivateClause(
13565 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13566 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13567 break;
13568 case OMPC_shared:
13569 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13570 break;
13571 case OMPC_reduction:
13572 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13573, __PRETTY_FUNCTION__))
13573 "Unexpected lastprivate modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown
&& "Unexpected lastprivate modifier.") ? static_cast
<void> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && \"Unexpected lastprivate modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13573, __PRETTY_FUNCTION__))
;
13574 Res = ActOnOpenMPReductionClause(
13575 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13576 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13577 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13578 break;
13579 case OMPC_task_reduction:
13580 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13581 EndLoc, ReductionOrMapperIdScopeSpec,
13582 ReductionOrMapperId);
13583 break;
13584 case OMPC_in_reduction:
13585 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13586 EndLoc, ReductionOrMapperIdScopeSpec,
13587 ReductionOrMapperId);
13588 break;
13589 case OMPC_linear:
13590 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13591, __PRETTY_FUNCTION__))
13591 "Unexpected linear modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown
&& "Unexpected linear modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && \"Unexpected linear modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13591, __PRETTY_FUNCTION__))
;
13592 Res = ActOnOpenMPLinearClause(
13593 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13594 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13595 ColonLoc, EndLoc);
13596 break;
13597 case OMPC_aligned:
13598 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13599 LParenLoc, ColonLoc, EndLoc);
13600 break;
13601 case OMPC_copyin:
13602 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13603 break;
13604 case OMPC_copyprivate:
13605 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13606 break;
13607 case OMPC_flush:
13608 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13609 break;
13610 case OMPC_depend:
13611 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13612, __PRETTY_FUNCTION__))
13612 "Unexpected depend modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown
&& "Unexpected depend modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && \"Unexpected depend modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13612, __PRETTY_FUNCTION__))
;
13613 Res = ActOnOpenMPDependClause(
13614 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13615 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13616 break;
13617 case OMPC_map:
13618 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13619, __PRETTY_FUNCTION__))
13619 "Unexpected map modifier.")((0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown
&& "Unexpected map modifier.") ? static_cast<void
> (0) : __assert_fail ("0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && \"Unexpected map modifier.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13619, __PRETTY_FUNCTION__))
;
13620 Res = ActOnOpenMPMapClause(
13621 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13622 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13623 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13624 break;
13625 case OMPC_to:
13626 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
13627 ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
13628 ColonLoc, VarList, Locs);
13629 break;
13630 case OMPC_from:
13631 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
13632 ReductionOrMapperIdScopeSpec,
13633 ReductionOrMapperId, ColonLoc, VarList, Locs);
13634 break;
13635 case OMPC_use_device_ptr:
13636 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13637 break;
13638 case OMPC_use_device_addr:
13639 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13640 break;
13641 case OMPC_is_device_ptr:
13642 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13643 break;
13644 case OMPC_allocate:
13645 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13646 LParenLoc, ColonLoc, EndLoc);
13647 break;
13648 case OMPC_nontemporal:
13649 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13650 break;
13651 case OMPC_inclusive:
13652 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13653 break;
13654 case OMPC_exclusive:
13655 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13656 break;
13657 case OMPC_affinity:
13658 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13659 DepModOrTailExpr, VarList);
13660 break;
13661 case OMPC_if:
13662 case OMPC_depobj:
13663 case OMPC_final:
13664 case OMPC_num_threads:
13665 case OMPC_safelen:
13666 case OMPC_simdlen:
13667 case OMPC_allocator:
13668 case OMPC_collapse:
13669 case OMPC_default:
13670 case OMPC_proc_bind:
13671 case OMPC_schedule:
13672 case OMPC_ordered:
13673 case OMPC_nowait:
13674 case OMPC_untied:
13675 case OMPC_mergeable:
13676 case OMPC_threadprivate:
13677 case OMPC_read:
13678 case OMPC_write:
13679 case OMPC_update:
13680 case OMPC_capture:
13681 case OMPC_seq_cst:
13682 case OMPC_acq_rel:
13683 case OMPC_acquire:
13684 case OMPC_release:
13685 case OMPC_relaxed:
13686 case OMPC_device:
13687 case OMPC_threads:
13688 case OMPC_simd:
13689 case OMPC_num_teams:
13690 case OMPC_thread_limit:
13691 case OMPC_priority:
13692 case OMPC_grainsize:
13693 case OMPC_nogroup:
13694 case OMPC_num_tasks:
13695 case OMPC_hint:
13696 case OMPC_dist_schedule:
13697 case OMPC_defaultmap:
13698 case OMPC_unknown:
13699 case OMPC_uniform:
13700 case OMPC_unified_address:
13701 case OMPC_unified_shared_memory:
13702 case OMPC_reverse_offload:
13703 case OMPC_dynamic_allocators:
13704 case OMPC_atomic_default_mem_order:
13705 case OMPC_device_type:
13706 case OMPC_match:
13707 case OMPC_order:
13708 case OMPC_destroy:
13709 case OMPC_detach:
13710 case OMPC_uses_allocators:
13711 default:
13712 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13712)
;
13713 }
13714 return Res;
13715}
13716
13717ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13718 ExprObjectKind OK, SourceLocation Loc) {
13719 ExprResult Res = BuildDeclRefExpr(
13720 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13721 if (!Res.isUsable())
13722 return ExprError();
13723 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13724 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13725 if (!Res.isUsable())
13726 return ExprError();
13727 }
13728 if (VK != VK_LValue && Res.get()->isGLValue()) {
13729 Res = DefaultLvalueConversion(Res.get());
13730 if (!Res.isUsable())
13731 return ExprError();
13732 }
13733 return Res;
13734}
13735
13736OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13737 SourceLocation StartLoc,
13738 SourceLocation LParenLoc,
13739 SourceLocation EndLoc) {
13740 SmallVector<Expr *, 8> Vars;
13741 SmallVector<Expr *, 8> PrivateCopies;
13742 for (Expr *RefExpr : VarList) {
13743 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13743, __PRETTY_FUNCTION__))
;
13744 SourceLocation ELoc;
13745 SourceRange ERange;
13746 Expr *SimpleRefExpr = RefExpr;
13747 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13748 if (Res.second) {
13749 // It will be analyzed later.
13750 Vars.push_back(RefExpr);
13751 PrivateCopies.push_back(nullptr);
13752 }
13753 ValueDecl *D = Res.first;
13754 if (!D)
13755 continue;
13756
13757 QualType Type = D->getType();
13758 auto *VD = dyn_cast<VarDecl>(D);
13759
13760 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13761 // A variable that appears in a private clause must not have an incomplete
13762 // type or a reference type.
13763 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13764 continue;
13765 Type = Type.getNonReferenceType();
13766
13767 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13768 // A variable that is privatized must not have a const-qualified type
13769 // unless it is of class type with a mutable member. This restriction does
13770 // not apply to the firstprivate clause.
13771 //
13772 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13773 // A variable that appears in a private clause must not have a
13774 // const-qualified type unless it is of class type with a mutable member.
13775 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13776 continue;
13777
13778 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13779 // in a Construct]
13780 // Variables with the predetermined data-sharing attributes may not be
13781 // listed in data-sharing attributes clauses, except for the cases
13782 // listed below. For these exceptions only, listing a predetermined
13783 // variable in a data-sharing attribute clause is allowed and overrides
13784 // the variable's predetermined data-sharing attributes.
13785 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13786 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13787 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13788 << getOpenMPClauseName(OMPC_private);
13789 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13790 continue;
13791 }
13792
13793 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13794 // Variably modified types are not supported for tasks.
13795 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13796 isOpenMPTaskingDirective(CurrDir)) {
13797 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13798 << getOpenMPClauseName(OMPC_private) << Type
13799 << getOpenMPDirectiveName(CurrDir);
13800 bool IsDecl =
13801 !VD ||
13802 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13803 Diag(D->getLocation(),
13804 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13805 << D;
13806 continue;
13807 }
13808
13809 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13810 // A list item cannot appear in both a map clause and a data-sharing
13811 // attribute clause on the same construct
13812 //
13813 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13814 // A list item cannot appear in both a map clause and a data-sharing
13815 // attribute clause on the same construct unless the construct is a
13816 // combined construct.
13817 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13818 CurrDir == OMPD_target) {
13819 OpenMPClauseKind ConflictKind;
13820 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
13821 VD, /*CurrentRegionOnly=*/true,
13822 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13823 OpenMPClauseKind WhereFoundClauseKind) -> bool {
13824 ConflictKind = WhereFoundClauseKind;
13825 return true;
13826 })) {
13827 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13828 << getOpenMPClauseName(OMPC_private)
13829 << getOpenMPClauseName(ConflictKind)
13830 << getOpenMPDirectiveName(CurrDir);
13831 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13832 continue;
13833 }
13834 }
13835
13836 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13837 // A variable of class type (or array thereof) that appears in a private
13838 // clause requires an accessible, unambiguous default constructor for the
13839 // class type.
13840 // Generate helper private variable and initialize it with the default
13841 // value. The address of the original variable is replaced by the address of
13842 // the new private variable in CodeGen. This new variable is not added to
13843 // IdResolver, so the code in the OpenMP region uses original variable for
13844 // proper diagnostics.
13845 Type = Type.getUnqualifiedType();
13846 VarDecl *VDPrivate =
13847 buildVarDecl(*this, ELoc, Type, D->getName(),
13848 D->hasAttrs() ? &D->getAttrs() : nullptr,
13849 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13850 ActOnUninitializedDecl(VDPrivate);
13851 if (VDPrivate->isInvalidDecl())
13852 continue;
13853 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13854 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13855
13856 DeclRefExpr *Ref = nullptr;
13857 if (!VD && !CurContext->isDependentContext())
13858 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13859 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13860 Vars.push_back((VD || CurContext->isDependentContext())
13861 ? RefExpr->IgnoreParens()
13862 : Ref);
13863 PrivateCopies.push_back(VDPrivateRefExpr);
13864 }
13865
13866 if (Vars.empty())
13867 return nullptr;
13868
13869 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13870 PrivateCopies);
13871}
13872
13873namespace {
13874class DiagsUninitializedSeveretyRAII {
13875private:
13876 DiagnosticsEngine &Diags;
13877 SourceLocation SavedLoc;
13878 bool IsIgnored = false;
13879
13880public:
13881 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
13882 bool IsIgnored)
13883 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
13884 if (!IsIgnored) {
13885 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
13886 /*Map*/ diag::Severity::Ignored, Loc);
13887 }
13888 }
13889 ~DiagsUninitializedSeveretyRAII() {
13890 if (!IsIgnored)
13891 Diags.popMappings(SavedLoc);
13892 }
13893};
13894}
13895
13896OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
13897 SourceLocation StartLoc,
13898 SourceLocation LParenLoc,
13899 SourceLocation EndLoc) {
13900 SmallVector<Expr *, 8> Vars;
13901 SmallVector<Expr *, 8> PrivateCopies;
13902 SmallVector<Expr *, 8> Inits;
13903 SmallVector<Decl *, 4> ExprCaptures;
13904 bool IsImplicitClause =
13905 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
13906 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
13907
13908 for (Expr *RefExpr : VarList) {
13909 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((RefExpr && "NULL expr in OpenMP firstprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 13909, __PRETTY_FUNCTION__))
;
13910 SourceLocation ELoc;
13911 SourceRange ERange;
13912 Expr *SimpleRefExpr = RefExpr;
13913 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13914 if (Res.second) {
13915 // It will be analyzed later.
13916 Vars.push_back(RefExpr);
13917 PrivateCopies.push_back(nullptr);
13918 Inits.push_back(nullptr);
13919 }
13920 ValueDecl *D = Res.first;
13921 if (!D)
13922 continue;
13923
13924 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
13925 QualType Type = D->getType();
13926 auto *VD = dyn_cast<VarDecl>(D);
13927
13928 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13929 // A variable that appears in a private clause must not have an incomplete
13930 // type or a reference type.
13931 if (RequireCompleteType(ELoc, Type,
13932 diag::err_omp_firstprivate_incomplete_type))
13933 continue;
13934 Type = Type.getNonReferenceType();
13935
13936 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
13937 // A variable of class type (or array thereof) that appears in a private
13938 // clause requires an accessible, unambiguous copy constructor for the
13939 // class type.
13940 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
13941
13942 // If an implicit firstprivate variable found it was checked already.
13943 DSAStackTy::DSAVarData TopDVar;
13944 if (!IsImplicitClause) {
13945 DSAStackTy::DSAVarData DVar =
13946 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13947 TopDVar = DVar;
13948 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13949 bool IsConstant = ElemType.isConstant(Context);
13950 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
13951 // A list item that specifies a given variable may not appear in more
13952 // than one clause on the same directive, except that a variable may be
13953 // specified in both firstprivate and lastprivate clauses.
13954 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13955 // A list item may appear in a firstprivate or lastprivate clause but not
13956 // both.
13957 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
13958 (isOpenMPDistributeDirective(CurrDir) ||
13959 DVar.CKind != OMPC_lastprivate) &&
13960 DVar.RefExpr) {
13961 Diag(ELoc, diag::err_omp_wrong_dsa)
13962 << getOpenMPClauseName(DVar.CKind)
13963 << getOpenMPClauseName(OMPC_firstprivate);
13964 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13965 continue;
13966 }
13967
13968 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13969 // in a Construct]
13970 // Variables with the predetermined data-sharing attributes may not be
13971 // listed in data-sharing attributes clauses, except for the cases
13972 // listed below. For these exceptions only, listing a predetermined
13973 // variable in a data-sharing attribute clause is allowed and overrides
13974 // the variable's predetermined data-sharing attributes.
13975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13976 // in a Construct, C/C++, p.2]
13977 // Variables with const-qualified type having no mutable member may be
13978 // listed in a firstprivate clause, even if they are static data members.
13979 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
13980 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
13981 Diag(ELoc, diag::err_omp_wrong_dsa)
13982 << getOpenMPClauseName(DVar.CKind)
13983 << getOpenMPClauseName(OMPC_firstprivate);
13984 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13985 continue;
13986 }
13987
13988 // OpenMP [2.9.3.4, Restrictions, p.2]
13989 // A list item that is private within a parallel region must not appear
13990 // in a firstprivate clause on a worksharing construct if any of the
13991 // worksharing regions arising from the worksharing construct ever bind
13992 // to any of the parallel regions arising from the parallel construct.
13993 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13994 // A list item that is private within a teams region must not appear in a
13995 // firstprivate clause on a distribute construct if any of the distribute
13996 // regions arising from the distribute construct ever bind to any of the
13997 // teams regions arising from the teams construct.
13998 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13999 // A list item that appears in a reduction clause of a teams construct
14000 // must not appear in a firstprivate clause on a distribute construct if
14001 // any of the distribute regions arising from the distribute construct
14002 // ever bind to any of the teams regions arising from the teams construct.
14003 if ((isOpenMPWorksharingDirective(CurrDir) ||
14004 isOpenMPDistributeDirective(CurrDir)) &&
14005 !isOpenMPParallelDirective(CurrDir) &&
14006 !isOpenMPTeamsDirective(CurrDir)) {
14007 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14008 if (DVar.CKind != OMPC_shared &&
14009 (isOpenMPParallelDirective(DVar.DKind) ||
14010 isOpenMPTeamsDirective(DVar.DKind) ||
14011 DVar.DKind == OMPD_unknown)) {
14012 Diag(ELoc, diag::err_omp_required_access)
14013 << getOpenMPClauseName(OMPC_firstprivate)
14014 << getOpenMPClauseName(OMPC_shared);
14015 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14016 continue;
14017 }
14018 }
14019 // OpenMP [2.9.3.4, Restrictions, p.3]
14020 // A list item that appears in a reduction clause of a parallel construct
14021 // must not appear in a firstprivate clause on a worksharing or task
14022 // construct if any of the worksharing or task regions arising from the
14023 // worksharing or task construct ever bind to any of the parallel regions
14024 // arising from the parallel construct.
14025 // OpenMP [2.9.3.4, Restrictions, p.4]
14026 // A list item that appears in a reduction clause in worksharing
14027 // construct must not appear in a firstprivate clause in a task construct
14028 // encountered during execution of any of the worksharing regions arising
14029 // from the worksharing construct.
14030 if (isOpenMPTaskingDirective(CurrDir)) {
14031 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
14032 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
14033 [](OpenMPDirectiveKind K) {
14034 return isOpenMPParallelDirective(K) ||
14035 isOpenMPWorksharingDirective(K) ||
14036 isOpenMPTeamsDirective(K);
14037 },
14038 /*FromParent=*/true);
14039 if (DVar.CKind == OMPC_reduction &&
14040 (isOpenMPParallelDirective(DVar.DKind) ||
14041 isOpenMPWorksharingDirective(DVar.DKind) ||
14042 isOpenMPTeamsDirective(DVar.DKind))) {
14043 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14044 << getOpenMPDirectiveName(DVar.DKind);
14045 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14046 continue;
14047 }
14048 }
14049
14050 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14051 // A list item cannot appear in both a map clause and a data-sharing
14052 // attribute clause on the same construct
14053 //
14054 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14055 // A list item cannot appear in both a map clause and a data-sharing
14056 // attribute clause on the same construct unless the construct is a
14057 // combined construct.
14058 if ((LangOpts.OpenMP <= 45 &&
14059 isOpenMPTargetExecutionDirective(CurrDir)) ||
14060 CurrDir == OMPD_target) {
14061 OpenMPClauseKind ConflictKind;
14062 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
14063 VD, /*CurrentRegionOnly=*/true,
14064 [&ConflictKind](
14065 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14066 OpenMPClauseKind WhereFoundClauseKind) {
14067 ConflictKind = WhereFoundClauseKind;
14068 return true;
14069 })) {
14070 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14071 << getOpenMPClauseName(OMPC_firstprivate)
14072 << getOpenMPClauseName(ConflictKind)
14073 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14074 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14075 continue;
14076 }
14077 }
14078 }
14079
14080 // Variably modified types are not supported for tasks.
14081 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14082 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
14083 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14084 << getOpenMPClauseName(OMPC_firstprivate) << Type
14085 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
14086 bool IsDecl =
14087 !VD ||
14088 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14089 Diag(D->getLocation(),
14090 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14091 << D;
14092 continue;
14093 }
14094
14095 Type = Type.getUnqualifiedType();
14096 VarDecl *VDPrivate =
14097 buildVarDecl(*this, ELoc, Type, D->getName(),
14098 D->hasAttrs() ? &D->getAttrs() : nullptr,
14099 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14100 // Generate helper private variable and initialize it with the value of the
14101 // original variable. The address of the original variable is replaced by
14102 // the address of the new private variable in the CodeGen. This new variable
14103 // is not added to IdResolver, so the code in the OpenMP region uses
14104 // original variable for proper diagnostics and variable capturing.
14105 Expr *VDInitRefExpr = nullptr;
14106 // For arrays generate initializer for single element and replace it by the
14107 // original array element in CodeGen.
14108 if (Type->isArrayType()) {
14109 VarDecl *VDInit =
14110 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14111 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14112 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14113 ElemType = ElemType.getUnqualifiedType();
14114 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14115 ".firstprivate.temp");
14116 InitializedEntity Entity =
14117 InitializedEntity::InitializeVariable(VDInitTemp);
14118 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14119
14120 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14121 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14122 if (Result.isInvalid())
14123 VDPrivate->setInvalidDecl();
14124 else
14125 VDPrivate->setInit(Result.getAs<Expr>());
14126 // Remove temp variable declaration.
14127 Context.Deallocate(VDInitTemp);
14128 } else {
14129 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14130 ".firstprivate.temp");
14131 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14132 RefExpr->getExprLoc());
14133 AddInitializerToDecl(VDPrivate,
14134 DefaultLvalueConversion(VDInitRefExpr).get(),
14135 /*DirectInit=*/false);
14136 }
14137 if (VDPrivate->isInvalidDecl()) {
14138 if (IsImplicitClause) {
14139 Diag(RefExpr->getExprLoc(),
14140 diag::note_omp_task_predetermined_firstprivate_here);
14141 }
14142 continue;
14143 }
14144 CurContext->addDecl(VDPrivate);
14145 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14146 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14147 RefExpr->getExprLoc());
14148 DeclRefExpr *Ref = nullptr;
14149 if (!VD && !CurContext->isDependentContext()) {
14150 if (TopDVar.CKind == OMPC_lastprivate) {
14151 Ref = TopDVar.PrivateCopy;
14152 } else {
14153 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14154 if (!isOpenMPCapturedDecl(D))
14155 ExprCaptures.push_back(Ref->getDecl());
14156 }
14157 }
14158 if (!IsImplicitClause)
14159 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14160 Vars.push_back((VD || CurContext->isDependentContext())
14161 ? RefExpr->IgnoreParens()
14162 : Ref);
14163 PrivateCopies.push_back(VDPrivateRefExpr);
14164 Inits.push_back(VDInitRefExpr);
14165 }
14166
14167 if (Vars.empty())
14168 return nullptr;
14169
14170 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14171 Vars, PrivateCopies, Inits,
14172 buildPreInits(Context, ExprCaptures));
14173}
14174
14175OMPClause *Sema::ActOnOpenMPLastprivateClause(
14176 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14177 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14178 SourceLocation LParenLoc, SourceLocation EndLoc) {
14179 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14180 assert(ColonLoc.isValid() && "Colon location must be valid.")((ColonLoc.isValid() && "Colon location must be valid."
) ? static_cast<void> (0) : __assert_fail ("ColonLoc.isValid() && \"Colon location must be valid.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14180, __PRETTY_FUNCTION__))
;
14181 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14182 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14183 /*Last=*/OMPC_LASTPRIVATE_unknown)
14184 << getOpenMPClauseName(OMPC_lastprivate);
14185 return nullptr;
14186 }
14187
14188 SmallVector<Expr *, 8> Vars;
14189 SmallVector<Expr *, 8> SrcExprs;
14190 SmallVector<Expr *, 8> DstExprs;
14191 SmallVector<Expr *, 8> AssignmentOps;
14192 SmallVector<Decl *, 4> ExprCaptures;
14193 SmallVector<Expr *, 4> ExprPostUpdates;
14194 for (Expr *RefExpr : VarList) {
14195 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14195, __PRETTY_FUNCTION__))
;
14196 SourceLocation ELoc;
14197 SourceRange ERange;
14198 Expr *SimpleRefExpr = RefExpr;
14199 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14200 if (Res.second) {
14201 // It will be analyzed later.
14202 Vars.push_back(RefExpr);
14203 SrcExprs.push_back(nullptr);
14204 DstExprs.push_back(nullptr);
14205 AssignmentOps.push_back(nullptr);
14206 }
14207 ValueDecl *D = Res.first;
14208 if (!D)
14209 continue;
14210
14211 QualType Type = D->getType();
14212 auto *VD = dyn_cast<VarDecl>(D);
14213
14214 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14215 // A variable that appears in a lastprivate clause must not have an
14216 // incomplete type or a reference type.
14217 if (RequireCompleteType(ELoc, Type,
14218 diag::err_omp_lastprivate_incomplete_type))
14219 continue;
14220 Type = Type.getNonReferenceType();
14221
14222 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14223 // A variable that is privatized must not have a const-qualified type
14224 // unless it is of class type with a mutable member. This restriction does
14225 // not apply to the firstprivate clause.
14226 //
14227 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14228 // A variable that appears in a lastprivate clause must not have a
14229 // const-qualified type unless it is of class type with a mutable member.
14230 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14231 continue;
14232
14233 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14234 // A list item that appears in a lastprivate clause with the conditional
14235 // modifier must be a scalar variable.
14236 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14237 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14238 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14239 VarDecl::DeclarationOnly;
14240 Diag(D->getLocation(),
14241 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14242 << D;
14243 continue;
14244 }
14245
14246 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
14247 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14248 // in a Construct]
14249 // Variables with the predetermined data-sharing attributes may not be
14250 // listed in data-sharing attributes clauses, except for the cases
14251 // listed below.
14252 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14253 // A list item may appear in a firstprivate or lastprivate clause but not
14254 // both.
14255 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14256 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14257 (isOpenMPDistributeDirective(CurrDir) ||
14258 DVar.CKind != OMPC_firstprivate) &&
14259 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14260 Diag(ELoc, diag::err_omp_wrong_dsa)
14261 << getOpenMPClauseName(DVar.CKind)
14262 << getOpenMPClauseName(OMPC_lastprivate);
14263 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14264 continue;
14265 }
14266
14267 // OpenMP [2.14.3.5, Restrictions, p.2]
14268 // A list item that is private within a parallel region, or that appears in
14269 // the reduction clause of a parallel construct, must not appear in a
14270 // lastprivate clause on a worksharing construct if any of the corresponding
14271 // worksharing regions ever binds to any of the corresponding parallel
14272 // regions.
14273 DSAStackTy::DSAVarData TopDVar = DVar;
14274 if (isOpenMPWorksharingDirective(CurrDir) &&
14275 !isOpenMPParallelDirective(CurrDir) &&
14276 !isOpenMPTeamsDirective(CurrDir)) {
14277 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
14278 if (DVar.CKind != OMPC_shared) {
14279 Diag(ELoc, diag::err_omp_required_access)
14280 << getOpenMPClauseName(OMPC_lastprivate)
14281 << getOpenMPClauseName(OMPC_shared);
14282 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14283 continue;
14284 }
14285 }
14286
14287 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14288 // A variable of class type (or array thereof) that appears in a
14289 // lastprivate clause requires an accessible, unambiguous default
14290 // constructor for the class type, unless the list item is also specified
14291 // in a firstprivate clause.
14292 // A variable of class type (or array thereof) that appears in a
14293 // lastprivate clause requires an accessible, unambiguous copy assignment
14294 // operator for the class type.
14295 Type = Context.getBaseElementType(Type).getNonReferenceType();
14296 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14297 Type.getUnqualifiedType(), ".lastprivate.src",
14298 D->hasAttrs() ? &D->getAttrs() : nullptr);
14299 DeclRefExpr *PseudoSrcExpr =
14300 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14301 VarDecl *DstVD =
14302 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14303 D->hasAttrs() ? &D->getAttrs() : nullptr);
14304 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14305 // For arrays generate assignment operation for single element and replace
14306 // it by the original array element in CodeGen.
14307 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14308 PseudoDstExpr, PseudoSrcExpr);
14309 if (AssignmentOp.isInvalid())
14310 continue;
14311 AssignmentOp =
14312 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14313 if (AssignmentOp.isInvalid())
14314 continue;
14315
14316 DeclRefExpr *Ref = nullptr;
14317 if (!VD && !CurContext->isDependentContext()) {
14318 if (TopDVar.CKind == OMPC_firstprivate) {
14319 Ref = TopDVar.PrivateCopy;
14320 } else {
14321 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14322 if (!isOpenMPCapturedDecl(D))
14323 ExprCaptures.push_back(Ref->getDecl());
14324 }
14325 if (TopDVar.CKind == OMPC_firstprivate ||
14326 (!isOpenMPCapturedDecl(D) &&
14327 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14328 ExprResult RefRes = DefaultLvalueConversion(Ref);
14329 if (!RefRes.isUsable())
14330 continue;
14331 ExprResult PostUpdateRes =
14332 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14333 RefRes.get());
14334 if (!PostUpdateRes.isUsable())
14335 continue;
14336 ExprPostUpdates.push_back(
14337 IgnoredValueConversions(PostUpdateRes.get()).get());
14338 }
14339 }
14340 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14341 Vars.push_back((VD || CurContext->isDependentContext())
14342 ? RefExpr->IgnoreParens()
14343 : Ref);
14344 SrcExprs.push_back(PseudoSrcExpr);
14345 DstExprs.push_back(PseudoDstExpr);
14346 AssignmentOps.push_back(AssignmentOp.get());
14347 }
14348
14349 if (Vars.empty())
14350 return nullptr;
14351
14352 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14353 Vars, SrcExprs, DstExprs, AssignmentOps,
14354 LPKind, LPKindLoc, ColonLoc,
14355 buildPreInits(Context, ExprCaptures),
14356 buildPostUpdate(*this, ExprPostUpdates));
14357}
14358
14359OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14360 SourceLocation StartLoc,
14361 SourceLocation LParenLoc,
14362 SourceLocation EndLoc) {
14363 SmallVector<Expr *, 8> Vars;
14364 for (Expr *RefExpr : VarList) {
14365 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14365, __PRETTY_FUNCTION__))
;
14366 SourceLocation ELoc;
14367 SourceRange ERange;
14368 Expr *SimpleRefExpr = RefExpr;
14369 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14370 if (Res.second) {
14371 // It will be analyzed later.
14372 Vars.push_back(RefExpr);
14373 }
14374 ValueDecl *D = Res.first;
14375 if (!D)
14376 continue;
14377
14378 auto *VD = dyn_cast<VarDecl>(D);
14379 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14380 // in a Construct]
14381 // Variables with the predetermined data-sharing attributes may not be
14382 // listed in data-sharing attributes clauses, except for the cases
14383 // listed below. For these exceptions only, listing a predetermined
14384 // variable in a data-sharing attribute clause is allowed and overrides
14385 // the variable's predetermined data-sharing attributes.
14386 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14387 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14388 DVar.RefExpr) {
14389 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14390 << getOpenMPClauseName(OMPC_shared);
14391 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14392 continue;
14393 }
14394
14395 DeclRefExpr *Ref = nullptr;
14396 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14397 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14398 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14399 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14400 ? RefExpr->IgnoreParens()
14401 : Ref);
14402 }
14403
14404 if (Vars.empty())
14405 return nullptr;
14406
14407 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14408}
14409
14410namespace {
14411class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14412 DSAStackTy *Stack;
14413
14414public:
14415 bool VisitDeclRefExpr(DeclRefExpr *E) {
14416 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14417 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14418 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14419 return false;
14420 if (DVar.CKind != OMPC_unknown)
14421 return true;
14422 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14423 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
14424 /*FromParent=*/true);
14425 return DVarPrivate.CKind != OMPC_unknown;
14426 }
14427 return false;
14428 }
14429 bool VisitStmt(Stmt *S) {
14430 for (Stmt *Child : S->children()) {
14431 if (Child && Visit(Child))
14432 return true;
14433 }
14434 return false;
14435 }
14436 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14437};
14438} // namespace
14439
14440namespace {
14441// Transform MemberExpression for specified FieldDecl of current class to
14442// DeclRefExpr to specified OMPCapturedExprDecl.
14443class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14444 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14445 ValueDecl *Field = nullptr;
14446 DeclRefExpr *CapturedExpr = nullptr;
14447
14448public:
14449 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14450 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14451
14452 ExprResult TransformMemberExpr(MemberExpr *E) {
14453 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14454 E->getMemberDecl() == Field) {
14455 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14456 return CapturedExpr;
14457 }
14458 return BaseTransform::TransformMemberExpr(E);
14459 }
14460 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14461};
14462} // namespace
14463
14464template <typename T, typename U>
14465static T filterLookupForUDReductionAndMapper(
14466 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14467 for (U &Set : Lookups) {
14468 for (auto *D : Set) {
14469 if (T Res = Gen(cast<ValueDecl>(D)))
14470 return Res;
14471 }
14472 }
14473 return T();
14474}
14475
14476static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14477 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case")((!LookupResult::isVisible(SemaRef, D) && "not in slow case"
) ? static_cast<void> (0) : __assert_fail ("!LookupResult::isVisible(SemaRef, D) && \"not in slow case\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14477, __PRETTY_FUNCTION__))
;
14478
14479 for (auto RD : D->redecls()) {
14480 // Don't bother with extra checks if we already know this one isn't visible.
14481 if (RD == D)
14482 continue;
14483
14484 auto ND = cast<NamedDecl>(RD);
14485 if (LookupResult::isVisible(SemaRef, ND))
14486 return ND;
14487 }
14488
14489 return nullptr;
14490}
14491
14492static void
14493argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14494 SourceLocation Loc, QualType Ty,
14495 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14496 // Find all of the associated namespaces and classes based on the
14497 // arguments we have.
14498 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14499 Sema::AssociatedClassSet AssociatedClasses;
14500 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14501 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14502 AssociatedClasses);
14503
14504 // C++ [basic.lookup.argdep]p3:
14505 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14506 // and let Y be the lookup set produced by argument dependent
14507 // lookup (defined as follows). If X contains [...] then Y is
14508 // empty. Otherwise Y is the set of declarations found in the
14509 // namespaces associated with the argument types as described
14510 // below. The set of declarations found by the lookup of the name
14511 // is the union of X and Y.
14512 //
14513 // Here, we compute Y and add its members to the overloaded
14514 // candidate set.
14515 for (auto *NS : AssociatedNamespaces) {
14516 // When considering an associated namespace, the lookup is the
14517 // same as the lookup performed when the associated namespace is
14518 // used as a qualifier (3.4.3.2) except that:
14519 //
14520 // -- Any using-directives in the associated namespace are
14521 // ignored.
14522 //
14523 // -- Any namespace-scope friend functions declared in
14524 // associated classes are visible within their respective
14525 // namespaces even if they are not visible during an ordinary
14526 // lookup (11.4).
14527 DeclContext::lookup_result R = NS->lookup(Id.getName());
14528 for (auto *D : R) {
14529 auto *Underlying = D;
14530 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14531 Underlying = USD->getTargetDecl();
14532
14533 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14534 !isa<OMPDeclareMapperDecl>(Underlying))
14535 continue;
14536
14537 if (!SemaRef.isVisible(D)) {
14538 D = findAcceptableDecl(SemaRef, D);
14539 if (!D)
14540 continue;
14541 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14542 Underlying = USD->getTargetDecl();
14543 }
14544 Lookups.emplace_back();
14545 Lookups.back().addDecl(Underlying);
14546 }
14547 }
14548}
14549
14550static ExprResult
14551buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14552 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14553 const DeclarationNameInfo &ReductionId, QualType Ty,
14554 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14555 if (ReductionIdScopeSpec.isInvalid())
14556 return ExprError();
14557 SmallVector<UnresolvedSet<8>, 4> Lookups;
14558 if (S) {
14559 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14560 Lookup.suppressDiagnostics();
14561 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14562 NamedDecl *D = Lookup.getRepresentativeDecl();
14563 do {
14564 S = S->getParent();
14565 } while (S && !S->isDeclScope(D));
14566 if (S)
14567 S = S->getParent();
14568 Lookups.emplace_back();
14569 Lookups.back().append(Lookup.begin(), Lookup.end());
14570 Lookup.clear();
14571 }
14572 } else if (auto *ULE =
14573 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14574 Lookups.push_back(UnresolvedSet<8>());
14575 Decl *PrevD = nullptr;
14576 for (NamedDecl *D : ULE->decls()) {
14577 if (D == PrevD)
14578 Lookups.push_back(UnresolvedSet<8>());
14579 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14580 Lookups.back().addDecl(DRD);
14581 PrevD = D;
14582 }
14583 }
14584 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14585 Ty->isInstantiationDependentType() ||
14586 Ty->containsUnexpandedParameterPack() ||
14587 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14588 return !D->isInvalidDecl() &&
14589 (D->getType()->isDependentType() ||
14590 D->getType()->isInstantiationDependentType() ||
14591 D->getType()->containsUnexpandedParameterPack());
14592 })) {
14593 UnresolvedSet<8> ResSet;
14594 for (const UnresolvedSet<8> &Set : Lookups) {
14595 if (Set.empty())
14596 continue;
14597 ResSet.append(Set.begin(), Set.end());
14598 // The last item marks the end of all declarations at the specified scope.
14599 ResSet.addDecl(Set[Set.size() - 1]);
14600 }
14601 return UnresolvedLookupExpr::Create(
14602 SemaRef.Context, /*NamingClass=*/nullptr,
14603 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14604 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14605 }
14606 // Lookup inside the classes.
14607 // C++ [over.match.oper]p3:
14608 // For a unary operator @ with an operand of a type whose
14609 // cv-unqualified version is T1, and for a binary operator @ with
14610 // a left operand of a type whose cv-unqualified version is T1 and
14611 // a right operand of a type whose cv-unqualified version is T2,
14612 // three sets of candidate functions, designated member
14613 // candidates, non-member candidates and built-in candidates, are
14614 // constructed as follows:
14615 // -- If T1 is a complete class type or a class currently being
14616 // defined, the set of member candidates is the result of the
14617 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14618 // the set of member candidates is empty.
14619 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14620 Lookup.suppressDiagnostics();
14621 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14622 // Complete the type if it can be completed.
14623 // If the type is neither complete nor being defined, bail out now.
14624 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14625 TyRec->getDecl()->getDefinition()) {
14626 Lookup.clear();
14627 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14628 if (Lookup.empty()) {
14629 Lookups.emplace_back();
14630 Lookups.back().append(Lookup.begin(), Lookup.end());
14631 }
14632 }
14633 }
14634 // Perform ADL.
14635 if (SemaRef.getLangOpts().CPlusPlus)
14636 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14637 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14638 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14639 if (!D->isInvalidDecl() &&
14640 SemaRef.Context.hasSameType(D->getType(), Ty))
14641 return D;
14642 return nullptr;
14643 }))
14644 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14645 VK_LValue, Loc);
14646 if (SemaRef.getLangOpts().CPlusPlus) {
14647 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14648 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14649 if (!D->isInvalidDecl() &&
14650 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14651 !Ty.isMoreQualifiedThan(D->getType()))
14652 return D;
14653 return nullptr;
14654 })) {
14655 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14656 /*DetectVirtual=*/false);
14657 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14658 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14659 VD->getType().getUnqualifiedType()))) {
14660 if (SemaRef.CheckBaseClassAccess(
14661 Loc, VD->getType(), Ty, Paths.front(),
14662 /*DiagID=*/0) != Sema::AR_inaccessible) {
14663 SemaRef.BuildBasePathArray(Paths, BasePath);
14664 return SemaRef.BuildDeclRefExpr(
14665 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14666 }
14667 }
14668 }
14669 }
14670 }
14671 if (ReductionIdScopeSpec.isSet()) {
14672 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14673 << Ty << Range;
14674 return ExprError();
14675 }
14676 return ExprEmpty();
14677}
14678
14679namespace {
14680/// Data for the reduction-based clauses.
14681struct ReductionData {
14682 /// List of original reduction items.
14683 SmallVector<Expr *, 8> Vars;
14684 /// List of private copies of the reduction items.
14685 SmallVector<Expr *, 8> Privates;
14686 /// LHS expressions for the reduction_op expressions.
14687 SmallVector<Expr *, 8> LHSs;
14688 /// RHS expressions for the reduction_op expressions.
14689 SmallVector<Expr *, 8> RHSs;
14690 /// Reduction operation expression.
14691 SmallVector<Expr *, 8> ReductionOps;
14692 /// inscan copy operation expressions.
14693 SmallVector<Expr *, 8> InscanCopyOps;
14694 /// inscan copy temp array expressions for prefix sums.
14695 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14696 /// inscan copy temp array element expressions for prefix sums.
14697 SmallVector<Expr *, 8> InscanCopyArrayElems;
14698 /// Taskgroup descriptors for the corresponding reduction items in
14699 /// in_reduction clauses.
14700 SmallVector<Expr *, 8> TaskgroupDescriptors;
14701 /// List of captures for clause.
14702 SmallVector<Decl *, 4> ExprCaptures;
14703 /// List of postupdate expressions.
14704 SmallVector<Expr *, 4> ExprPostUpdates;
14705 /// Reduction modifier.
14706 unsigned RedModifier = 0;
14707 ReductionData() = delete;
14708 /// Reserves required memory for the reduction data.
14709 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14710 Vars.reserve(Size);
14711 Privates.reserve(Size);
14712 LHSs.reserve(Size);
14713 RHSs.reserve(Size);
14714 ReductionOps.reserve(Size);
14715 if (RedModifier == OMPC_REDUCTION_inscan) {
14716 InscanCopyOps.reserve(Size);
14717 InscanCopyArrayTemps.reserve(Size);
14718 InscanCopyArrayElems.reserve(Size);
14719 }
14720 TaskgroupDescriptors.reserve(Size);
14721 ExprCaptures.reserve(Size);
14722 ExprPostUpdates.reserve(Size);
14723 }
14724 /// Stores reduction item and reduction operation only (required for dependent
14725 /// reduction item).
14726 void push(Expr *Item, Expr *ReductionOp) {
14727 Vars.emplace_back(Item);
14728 Privates.emplace_back(nullptr);
14729 LHSs.emplace_back(nullptr);
14730 RHSs.emplace_back(nullptr);
14731 ReductionOps.emplace_back(ReductionOp);
14732 TaskgroupDescriptors.emplace_back(nullptr);
14733 if (RedModifier == OMPC_REDUCTION_inscan) {
14734 InscanCopyOps.push_back(nullptr);
14735 InscanCopyArrayTemps.push_back(nullptr);
14736 InscanCopyArrayElems.push_back(nullptr);
14737 }
14738 }
14739 /// Stores reduction data.
14740 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14741 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14742 Expr *CopyArrayElem) {
14743 Vars.emplace_back(Item);
14744 Privates.emplace_back(Private);
14745 LHSs.emplace_back(LHS);
14746 RHSs.emplace_back(RHS);
14747 ReductionOps.emplace_back(ReductionOp);
14748 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14749 if (RedModifier == OMPC_REDUCTION_inscan) {
14750 InscanCopyOps.push_back(CopyOp);
14751 InscanCopyArrayTemps.push_back(CopyArrayTemp);
14752 InscanCopyArrayElems.push_back(CopyArrayElem);
14753 } else {
14754 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14756, __PRETTY_FUNCTION__))
14755 CopyArrayElem == nullptr &&((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14756, __PRETTY_FUNCTION__))
14756 "Copy operation must be used for inscan reductions only.")((CopyOp == nullptr && CopyArrayTemp == nullptr &&
CopyArrayElem == nullptr && "Copy operation must be used for inscan reductions only."
) ? static_cast<void> (0) : __assert_fail ("CopyOp == nullptr && CopyArrayTemp == nullptr && CopyArrayElem == nullptr && \"Copy operation must be used for inscan reductions only.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14756, __PRETTY_FUNCTION__))
;
14757 }
14758 }
14759};
14760} // namespace
14761
14762static bool checkOMPArraySectionConstantForReduction(
14763 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14764 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14765 const Expr *Length = OASE->getLength();
14766 if (Length == nullptr) {
14767 // For array sections of the form [1:] or [:], we would need to analyze
14768 // the lower bound...
14769 if (OASE->getColonLocFirst().isValid())
14770 return false;
14771
14772 // This is an array subscript which has implicit length 1!
14773 SingleElement = true;
14774 ArraySizes.push_back(llvm::APSInt::get(1));
14775 } else {
14776 Expr::EvalResult Result;
14777 if (!Length->EvaluateAsInt(Result, Context))
14778 return false;
14779
14780 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14781 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14782 ArraySizes.push_back(ConstantLengthValue);
14783 }
14784
14785 // Get the base of this array section and walk up from there.
14786 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14787
14788 // We require length = 1 for all array sections except the right-most to
14789 // guarantee that the memory region is contiguous and has no holes in it.
14790 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14791 Length = TempOASE->getLength();
14792 if (Length == nullptr) {
14793 // For array sections of the form [1:] or [:], we would need to analyze
14794 // the lower bound...
14795 if (OASE->getColonLocFirst().isValid())
14796 return false;
14797
14798 // This is an array subscript which has implicit length 1!
14799 ArraySizes.push_back(llvm::APSInt::get(1));
14800 } else {
14801 Expr::EvalResult Result;
14802 if (!Length->EvaluateAsInt(Result, Context))
14803 return false;
14804
14805 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14806 if (ConstantLengthValue.getSExtValue() != 1)
14807 return false;
14808
14809 ArraySizes.push_back(ConstantLengthValue);
14810 }
14811 Base = TempOASE->getBase()->IgnoreParenImpCasts();
14812 }
14813
14814 // If we have a single element, we don't need to add the implicit lengths.
14815 if (!SingleElement) {
14816 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14817 // Has implicit length 1!
14818 ArraySizes.push_back(llvm::APSInt::get(1));
14819 Base = TempASE->getBase()->IgnoreParenImpCasts();
14820 }
14821 }
14822
14823 // This array section can be privatized as a single value or as a constant
14824 // sized array.
14825 return true;
14826}
14827
14828static bool actOnOMPReductionKindClause(
14829 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14830 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14831 SourceLocation ColonLoc, SourceLocation EndLoc,
14832 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14833 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14834 DeclarationName DN = ReductionId.getName();
14835 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14836 BinaryOperatorKind BOK = BO_Comma;
14837
14838 ASTContext &Context = S.Context;
14839 // OpenMP [2.14.3.6, reduction clause]
14840 // C
14841 // reduction-identifier is either an identifier or one of the following
14842 // operators: +, -, *, &, |, ^, && and ||
14843 // C++
14844 // reduction-identifier is either an id-expression or one of the following
14845 // operators: +, -, *, &, |, ^, && and ||
14846 switch (OOK) {
14847 case OO_Plus:
14848 case OO_Minus:
14849 BOK = BO_Add;
14850 break;
14851 case OO_Star:
14852 BOK = BO_Mul;
14853 break;
14854 case OO_Amp:
14855 BOK = BO_And;
14856 break;
14857 case OO_Pipe:
14858 BOK = BO_Or;
14859 break;
14860 case OO_Caret:
14861 BOK = BO_Xor;
14862 break;
14863 case OO_AmpAmp:
14864 BOK = BO_LAnd;
14865 break;
14866 case OO_PipePipe:
14867 BOK = BO_LOr;
14868 break;
14869 case OO_New:
14870 case OO_Delete:
14871 case OO_Array_New:
14872 case OO_Array_Delete:
14873 case OO_Slash:
14874 case OO_Percent:
14875 case OO_Tilde:
14876 case OO_Exclaim:
14877 case OO_Equal:
14878 case OO_Less:
14879 case OO_Greater:
14880 case OO_LessEqual:
14881 case OO_GreaterEqual:
14882 case OO_PlusEqual:
14883 case OO_MinusEqual:
14884 case OO_StarEqual:
14885 case OO_SlashEqual:
14886 case OO_PercentEqual:
14887 case OO_CaretEqual:
14888 case OO_AmpEqual:
14889 case OO_PipeEqual:
14890 case OO_LessLess:
14891 case OO_GreaterGreater:
14892 case OO_LessLessEqual:
14893 case OO_GreaterGreaterEqual:
14894 case OO_EqualEqual:
14895 case OO_ExclaimEqual:
14896 case OO_Spaceship:
14897 case OO_PlusPlus:
14898 case OO_MinusMinus:
14899 case OO_Comma:
14900 case OO_ArrowStar:
14901 case OO_Arrow:
14902 case OO_Call:
14903 case OO_Subscript:
14904 case OO_Conditional:
14905 case OO_Coawait:
14906 case NUM_OVERLOADED_OPERATORS:
14907 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14907)
;
14908 case OO_None:
14909 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
14910 if (II->isStr("max"))
14911 BOK = BO_GT;
14912 else if (II->isStr("min"))
14913 BOK = BO_LT;
14914 }
14915 break;
14916 }
14917 SourceRange ReductionIdRange;
14918 if (ReductionIdScopeSpec.isValid())
14919 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
14920 else
14921 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
14922 ReductionIdRange.setEnd(ReductionId.getEndLoc());
14923
14924 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
14925 bool FirstIter = true;
14926 for (Expr *RefExpr : VarList) {
14927 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((RefExpr && "nullptr expr in OpenMP reduction clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 14927, __PRETTY_FUNCTION__))
;
14928 // OpenMP [2.1, C/C++]
14929 // A list item is a variable or array section, subject to the restrictions
14930 // specified in Section 2.4 on page 42 and in each of the sections
14931 // describing clauses and directives for which a list appears.
14932 // OpenMP [2.14.3.3, Restrictions, p.1]
14933 // A variable that is part of another variable (as an array or
14934 // structure element) cannot appear in a private clause.
14935 if (!FirstIter && IR != ER)
14936 ++IR;
14937 FirstIter = false;
14938 SourceLocation ELoc;
14939 SourceRange ERange;
14940 Expr *SimpleRefExpr = RefExpr;
14941 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
14942 /*AllowArraySection=*/true);
14943 if (Res.second) {
14944 // Try to find 'declare reduction' corresponding construct before using
14945 // builtin/overloaded operators.
14946 QualType Type = Context.DependentTy;
14947 CXXCastPath BasePath;
14948 ExprResult DeclareReductionRef = buildDeclareReductionRef(
14949 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
14950 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
14951 Expr *ReductionOp = nullptr;
14952 if (S.CurContext->isDependentContext() &&
14953 (DeclareReductionRef.isUnset() ||
14954 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
14955 ReductionOp = DeclareReductionRef.get();
14956 // It will be analyzed later.
14957 RD.push(RefExpr, ReductionOp);
14958 }
14959 ValueDecl *D = Res.first;
14960 if (!D)
14961 continue;
14962
14963 Expr *TaskgroupDescriptor = nullptr;
14964 QualType Type;
14965 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
14966 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
14967 if (ASE) {
14968 Type = ASE->getType().getNonReferenceType();
14969 } else if (OASE) {
14970 QualType BaseType =
14971 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
14972 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
14973 Type = ATy->getElementType();
14974 else
14975 Type = BaseType->getPointeeType();
14976 Type = Type.getNonReferenceType();
14977 } else {
14978 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
14979 }
14980 auto *VD = dyn_cast<VarDecl>(D);
14981
14982 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14983 // A variable that appears in a private clause must not have an incomplete
14984 // type or a reference type.
14985 if (S.RequireCompleteType(ELoc, D->getType(),
14986 diag::err_omp_reduction_incomplete_type))
14987 continue;
14988 // OpenMP [2.14.3.6, reduction clause, Restrictions]
14989 // A list item that appears in a reduction clause must not be
14990 // const-qualified.
14991 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
14992 /*AcceptIfMutable*/ false, ASE || OASE))
14993 continue;
14994
14995 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
14996 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
14997 // If a list-item is a reference type then it must bind to the same object
14998 // for all threads of the team.
14999 if (!ASE && !OASE) {
15000 if (VD) {
15001 VarDecl *VDDef = VD->getDefinition();
15002 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
15003 DSARefChecker Check(Stack);
15004 if (Check.Visit(VDDef->getInit())) {
15005 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
15006 << getOpenMPClauseName(ClauseKind) << ERange;
15007 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
15008 continue;
15009 }
15010 }
15011 }
15012
15013 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15014 // in a Construct]
15015 // Variables with the predetermined data-sharing attributes may not be
15016 // listed in data-sharing attributes clauses, except for the cases
15017 // listed below. For these exceptions only, listing a predetermined
15018 // variable in a data-sharing attribute clause is allowed and overrides
15019 // the variable's predetermined data-sharing attributes.
15020 // OpenMP [2.14.3.6, Restrictions, p.3]
15021 // Any number of reduction clauses can be specified on the directive,
15022 // but a list item can appear only once in the reduction clauses for that
15023 // directive.
15024 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15025 if (DVar.CKind == OMPC_reduction) {
15026 S.Diag(ELoc, diag::err_omp_once_referenced)
15027 << getOpenMPClauseName(ClauseKind);
15028 if (DVar.RefExpr)
15029 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15030 continue;
15031 }
15032 if (DVar.CKind != OMPC_unknown) {
15033 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15034 << getOpenMPClauseName(DVar.CKind)
15035 << getOpenMPClauseName(OMPC_reduction);
15036 reportOriginalDsa(S, Stack, D, DVar);
15037 continue;
15038 }
15039
15040 // OpenMP [2.14.3.6, Restrictions, p.1]
15041 // A list item that appears in a reduction clause of a worksharing
15042 // construct must be shared in the parallel regions to which any of the
15043 // worksharing regions arising from the worksharing construct bind.
15044 if (isOpenMPWorksharingDirective(CurrDir) &&
15045 !isOpenMPParallelDirective(CurrDir) &&
15046 !isOpenMPTeamsDirective(CurrDir)) {
15047 DVar = Stack->getImplicitDSA(D, true);
15048 if (DVar.CKind != OMPC_shared) {
15049 S.Diag(ELoc, diag::err_omp_required_access)
15050 << getOpenMPClauseName(OMPC_reduction)
15051 << getOpenMPClauseName(OMPC_shared);
15052 reportOriginalDsa(S, Stack, D, DVar);
15053 continue;
15054 }
15055 }
15056 }
15057
15058 // Try to find 'declare reduction' corresponding construct before using
15059 // builtin/overloaded operators.
15060 CXXCastPath BasePath;
15061 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15062 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15063 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15064 if (DeclareReductionRef.isInvalid())
15065 continue;
15066 if (S.CurContext->isDependentContext() &&
15067 (DeclareReductionRef.isUnset() ||
15068 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15069 RD.push(RefExpr, DeclareReductionRef.get());
15070 continue;
15071 }
15072 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15073 // Not allowed reduction identifier is found.
15074 S.Diag(ReductionId.getBeginLoc(),
15075 diag::err_omp_unknown_reduction_identifier)
15076 << Type << ReductionIdRange;
15077 continue;
15078 }
15079
15080 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15081 // The type of a list item that appears in a reduction clause must be valid
15082 // for the reduction-identifier. For a max or min reduction in C, the type
15083 // of the list item must be an allowed arithmetic data type: char, int,
15084 // float, double, or _Bool, possibly modified with long, short, signed, or
15085 // unsigned. For a max or min reduction in C++, the type of the list item
15086 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15087 // double, or bool, possibly modified with long, short, signed, or unsigned.
15088 if (DeclareReductionRef.isUnset()) {
15089 if ((BOK == BO_GT || BOK == BO_LT) &&
15090 !(Type->isScalarType() ||
15091 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15092 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15093 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15094 if (!ASE && !OASE) {
15095 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15096 VarDecl::DeclarationOnly;
15097 S.Diag(D->getLocation(),
15098 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15099 << D;
15100 }
15101 continue;
15102 }
15103 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15104 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15105 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15106 << getOpenMPClauseName(ClauseKind);
15107 if (!ASE && !OASE) {
15108 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15109 VarDecl::DeclarationOnly;
15110 S.Diag(D->getLocation(),
15111 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15112 << D;
15113 }
15114 continue;
15115 }
15116 }
15117
15118 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15119 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15120 D->hasAttrs() ? &D->getAttrs() : nullptr);
15121 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15122 D->hasAttrs() ? &D->getAttrs() : nullptr);
15123 QualType PrivateTy = Type;
15124
15125 // Try if we can determine constant lengths for all array sections and avoid
15126 // the VLA.
15127 bool ConstantLengthOASE = false;
15128 if (OASE) {
15129 bool SingleElement;
15130 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15131 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15132 Context, OASE, SingleElement, ArraySizes);
15133
15134 // If we don't have a single element, we must emit a constant array type.
15135 if (ConstantLengthOASE && !SingleElement) {
15136 for (llvm::APSInt &Size : ArraySizes)
15137 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15138 ArrayType::Normal,
15139 /*IndexTypeQuals=*/0);
15140 }
15141 }
15142
15143 if ((OASE && !ConstantLengthOASE) ||
15144 (!OASE && !ASE &&
15145 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15146 if (!Context.getTargetInfo().isVLASupported()) {
15147 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15148 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15149 S.Diag(ELoc, diag::note_vla_unsupported);
15150 continue;
15151 } else {
15152 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15153 S.targetDiag(ELoc, diag::note_vla_unsupported);
15154 }
15155 }
15156 // For arrays/array sections only:
15157 // Create pseudo array type for private copy. The size for this array will
15158 // be generated during codegen.
15159 // For array subscripts or single variables Private Ty is the same as Type
15160 // (type of the variable or single array element).
15161 PrivateTy = Context.getVariableArrayType(
15162 Type,
15163 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15164 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15165 } else if (!ASE && !OASE &&
15166 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15167 PrivateTy = D->getType().getNonReferenceType();
15168 }
15169 // Private copy.
15170 VarDecl *PrivateVD =
15171 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15172 D->hasAttrs() ? &D->getAttrs() : nullptr,
15173 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15174 // Add initializer for private variable.
15175 Expr *Init = nullptr;
15176 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15177 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15178 if (DeclareReductionRef.isUsable()) {
15179 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15180 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15181 if (DRD->getInitializer()) {
15182 S.ActOnUninitializedDecl(PrivateVD);
15183 Init = DRDRef;
15184 RHSVD->setInit(DRDRef);
15185 RHSVD->setInitStyle(VarDecl::CallInit);
15186 }
15187 } else {
15188 switch (BOK) {
15189 case BO_Add:
15190 case BO_Xor:
15191 case BO_Or:
15192 case BO_LOr:
15193 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15194 if (Type->isScalarType() || Type->isAnyComplexType())
15195 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15196 break;
15197 case BO_Mul:
15198 case BO_LAnd:
15199 if (Type->isScalarType() || Type->isAnyComplexType()) {
15200 // '*' and '&&' reduction ops - initializer is '1'.
15201 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15202 }
15203 break;
15204 case BO_And: {
15205 // '&' reduction op - initializer is '~0'.
15206 QualType OrigType = Type;
15207 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15208 Type = ComplexTy->getElementType();
15209 if (Type->isRealFloatingType()) {
15210 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15211 Context.getFloatTypeSemantics(Type),
15212 Context.getTypeSize(Type));
15213 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15214 Type, ELoc);
15215 } else if (Type->isScalarType()) {
15216 uint64_t Size = Context.getTypeSize(Type);
15217 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15218 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15219 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15220 }
15221 if (Init && OrigType->isAnyComplexType()) {
15222 // Init = 0xFFFF + 0xFFFFi;
15223 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15224 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15225 }
15226 Type = OrigType;
15227 break;
15228 }
15229 case BO_LT:
15230 case BO_GT: {
15231 // 'min' reduction op - initializer is 'Largest representable number in
15232 // the reduction list item type'.
15233 // 'max' reduction op - initializer is 'Least representable number in
15234 // the reduction list item type'.
15235 if (Type->isIntegerType() || Type->isPointerType()) {
15236 bool IsSigned = Type->hasSignedIntegerRepresentation();
15237 uint64_t Size = Context.getTypeSize(Type);
15238 QualType IntTy =
15239 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15240 llvm::APInt InitValue =
15241 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15242 : llvm::APInt::getMinValue(Size)
15243 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15244 : llvm::APInt::getMaxValue(Size);
15245 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15246 if (Type->isPointerType()) {
15247 // Cast to pointer type.
15248 ExprResult CastExpr = S.BuildCStyleCastExpr(
15249 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15250 if (CastExpr.isInvalid())
15251 continue;
15252 Init = CastExpr.get();
15253 }
15254 } else if (Type->isRealFloatingType()) {
15255 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15256 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15257 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15258 Type, ELoc);
15259 }
15260 break;
15261 }
15262 case BO_PtrMemD:
15263 case BO_PtrMemI:
15264 case BO_MulAssign:
15265 case BO_Div:
15266 case BO_Rem:
15267 case BO_Sub:
15268 case BO_Shl:
15269 case BO_Shr:
15270 case BO_LE:
15271 case BO_GE:
15272 case BO_EQ:
15273 case BO_NE:
15274 case BO_Cmp:
15275 case BO_AndAssign:
15276 case BO_XorAssign:
15277 case BO_OrAssign:
15278 case BO_Assign:
15279 case BO_AddAssign:
15280 case BO_SubAssign:
15281 case BO_DivAssign:
15282 case BO_RemAssign:
15283 case BO_ShlAssign:
15284 case BO_ShrAssign:
15285 case BO_Comma:
15286 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 15286)
;
15287 }
15288 }
15289 if (Init && DeclareReductionRef.isUnset()) {
15290 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15291 // Store initializer for single element in private copy. Will be used
15292 // during codegen.
15293 PrivateVD->setInit(RHSVD->getInit());
15294 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15295 } else if (!Init) {
15296 S.ActOnUninitializedDecl(RHSVD);
15297 // Store initializer for single element in private copy. Will be used
15298 // during codegen.
15299 PrivateVD->setInit(RHSVD->getInit());
15300 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15301 }
15302 if (RHSVD->isInvalidDecl())
15303 continue;
15304 if (!RHSVD->hasInit() &&
15305 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15306 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15307 << Type << ReductionIdRange;
15308 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15309 VarDecl::DeclarationOnly;
15310 S.Diag(D->getLocation(),
15311 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15312 << D;
15313 continue;
15314 }
15315 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15316 ExprResult ReductionOp;
15317 if (DeclareReductionRef.isUsable()) {
15318 QualType RedTy = DeclareReductionRef.get()->getType();
15319 QualType PtrRedTy = Context.getPointerType(RedTy);
15320 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15321 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15322 if (!BasePath.empty()) {
15323 LHS = S.DefaultLvalueConversion(LHS.get());
15324 RHS = S.DefaultLvalueConversion(RHS.get());
15325 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15326 CK_UncheckedDerivedToBase, LHS.get(),
15327 &BasePath, LHS.get()->getValueKind());
15328 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15329 CK_UncheckedDerivedToBase, RHS.get(),
15330 &BasePath, RHS.get()->getValueKind());
15331 }
15332 FunctionProtoType::ExtProtoInfo EPI;
15333 QualType Params[] = {PtrRedTy, PtrRedTy};
15334 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15335 auto *OVE = new (Context) OpaqueValueExpr(
15336 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15337 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15338 Expr *Args[] = {LHS.get(), RHS.get()};
15339 ReductionOp =
15340 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
15341 S.CurFPFeatureOverrides());
15342 } else {
15343 ReductionOp = S.BuildBinOp(
15344 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15345 if (ReductionOp.isUsable()) {
15346 if (BOK != BO_LT && BOK != BO_GT) {
15347 ReductionOp =
15348 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15349 BO_Assign, LHSDRE, ReductionOp.get());
15350 } else {
15351 auto *ConditionalOp = new (Context)
15352 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15353 Type, VK_LValue, OK_Ordinary);
15354 ReductionOp =
15355 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15356 BO_Assign, LHSDRE, ConditionalOp);
15357 }
15358 if (ReductionOp.isUsable())
15359 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15360 /*DiscardedValue*/ false);
15361 }
15362 if (!ReductionOp.isUsable())
15363 continue;
15364 }
15365
15366 // Add copy operations for inscan reductions.
15367 // LHS = RHS;
15368 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15369 if (ClauseKind == OMPC_reduction &&
15370 RD.RedModifier == OMPC_REDUCTION_inscan) {
15371 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15372 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15373 RHS.get());
15374 if (!CopyOpRes.isUsable())
15375 continue;
15376 CopyOpRes =
15377 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15378 if (!CopyOpRes.isUsable())
15379 continue;
15380 // For simd directive and simd-based directives in simd mode no need to
15381 // construct temp array, need just a single temp element.
15382 if (Stack->getCurrentDirective() == OMPD_simd ||
15383 (S.getLangOpts().OpenMPSimd &&
15384 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15385 VarDecl *TempArrayVD =
15386 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15387 D->hasAttrs() ? &D->getAttrs() : nullptr);
15388 // Add a constructor to the temp decl.
15389 S.ActOnUninitializedDecl(TempArrayVD);
15390 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15391 } else {
15392 // Build temp array for prefix sum.
15393 auto *Dim = new (S.Context)
15394 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15395 QualType ArrayTy =
15396 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15397 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15398 VarDecl *TempArrayVD =
15399 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15400 D->hasAttrs() ? &D->getAttrs() : nullptr);
15401 // Add a constructor to the temp decl.
15402 S.ActOnUninitializedDecl(TempArrayVD);
15403 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15404 TempArrayElem =
15405 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15406 auto *Idx = new (S.Context)
15407 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15408 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15409 ELoc, Idx, ELoc);
15410 }
15411 }
15412
15413 // OpenMP [2.15.4.6, Restrictions, p.2]
15414 // A list item that appears in an in_reduction clause of a task construct
15415 // must appear in a task_reduction clause of a construct associated with a
15416 // taskgroup region that includes the participating task in its taskgroup
15417 // set. The construct associated with the innermost region that meets this
15418 // condition must specify the same reduction-identifier as the in_reduction
15419 // clause.
15420 if (ClauseKind == OMPC_in_reduction) {
15421 SourceRange ParentSR;
15422 BinaryOperatorKind ParentBOK;
15423 const Expr *ParentReductionOp = nullptr;
15424 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15425 DSAStackTy::DSAVarData ParentBOKDSA =
15426 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15427 ParentBOKTD);
15428 DSAStackTy::DSAVarData ParentReductionOpDSA =
15429 Stack->getTopMostTaskgroupReductionData(
15430 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15431 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15432 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15433 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15434 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15435 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15436 bool EmitError = true;
15437 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15438 llvm::FoldingSetNodeID RedId, ParentRedId;
15439 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15440 DeclareReductionRef.get()->Profile(RedId, Context,
15441 /*Canonical=*/true);
15442 EmitError = RedId != ParentRedId;
15443 }
15444 if (EmitError) {
15445 S.Diag(ReductionId.getBeginLoc(),
15446 diag::err_omp_reduction_identifier_mismatch)
15447 << ReductionIdRange << RefExpr->getSourceRange();
15448 S.Diag(ParentSR.getBegin(),
15449 diag::note_omp_previous_reduction_identifier)
15450 << ParentSR
15451 << (IsParentBOK ? ParentBOKDSA.RefExpr
15452 : ParentReductionOpDSA.RefExpr)
15453 ->getSourceRange();
15454 continue;
15455 }
15456 }
15457 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15458 }
15459
15460 DeclRefExpr *Ref = nullptr;
15461 Expr *VarsExpr = RefExpr->IgnoreParens();
15462 if (!VD && !S.CurContext->isDependentContext()) {
15463 if (ASE || OASE) {
15464 TransformExprToCaptures RebuildToCapture(S, D);
15465 VarsExpr =
15466 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15467 Ref = RebuildToCapture.getCapturedExpr();
15468 } else {
15469 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15470 }
15471 if (!S.isOpenMPCapturedDecl(D)) {
15472 RD.ExprCaptures.emplace_back(Ref->getDecl());
15473 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15474 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15475 if (!RefRes.isUsable())
15476 continue;
15477 ExprResult PostUpdateRes =
15478 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15479 RefRes.get());
15480 if (!PostUpdateRes.isUsable())
15481 continue;
15482 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15483 Stack->getCurrentDirective() == OMPD_taskgroup) {
15484 S.Diag(RefExpr->getExprLoc(),
15485 diag::err_omp_reduction_non_addressable_expression)
15486 << RefExpr->getSourceRange();
15487 continue;
15488 }
15489 RD.ExprPostUpdates.emplace_back(
15490 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15491 }
15492 }
15493 }
15494 // All reduction items are still marked as reduction (to do not increase
15495 // code base size).
15496 unsigned Modifier = RD.RedModifier;
15497 // Consider task_reductions as reductions with task modifier. Required for
15498 // correct analysis of in_reduction clauses.
15499 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15500 Modifier = OMPC_REDUCTION_task;
15501 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier);
15502 if (Modifier == OMPC_REDUCTION_task &&
15503 (CurrDir == OMPD_taskgroup ||
15504 ((isOpenMPParallelDirective(CurrDir) ||
15505 isOpenMPWorksharingDirective(CurrDir)) &&
15506 !isOpenMPSimdDirective(CurrDir)))) {
15507 if (DeclareReductionRef.isUsable())
15508 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15509 DeclareReductionRef.get());
15510 else
15511 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15512 }
15513 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15514 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15515 TempArrayElem.get());
15516 }
15517 return RD.Vars.empty();
15518}
15519
15520OMPClause *Sema::ActOnOpenMPReductionClause(
15521 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15522 SourceLocation StartLoc, SourceLocation LParenLoc,
15523 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15524 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15525 ArrayRef<Expr *> UnresolvedReductions) {
15526 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15527 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15528 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15529 /*Last=*/OMPC_REDUCTION_unknown)
15530 << getOpenMPClauseName(OMPC_reduction);
15531 return nullptr;
15532 }
15533 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15534 // A reduction clause with the inscan reduction-modifier may only appear on a
15535 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15536 // construct, a parallel worksharing-loop construct or a parallel
15537 // worksharing-loop SIMD construct.
15538 if (Modifier == OMPC_REDUCTION_inscan &&
15539 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for &&
15540 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_for_simd &&
15541 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_simd &&
15542 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for &&
15543 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_parallel_for_simd)) {
15544 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15545 return nullptr;
15546 }
15547
15548 ReductionData RD(VarList.size(), Modifier);
15549 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
15550 StartLoc, LParenLoc, ColonLoc, EndLoc,
15551 ReductionIdScopeSpec, ReductionId,
15552 UnresolvedReductions, RD))
15553 return nullptr;
15554
15555 return OMPReductionClause::Create(
15556 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15557 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15558 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15559 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15560 buildPreInits(Context, RD.ExprCaptures),
15561 buildPostUpdate(*this, RD.ExprPostUpdates));
15562}
15563
15564OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15565 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15566 SourceLocation ColonLoc, SourceLocation EndLoc,
15567 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15568 ArrayRef<Expr *> UnresolvedReductions) {
15569 ReductionData RD(VarList.size());
15570 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
15571 StartLoc, LParenLoc, ColonLoc, EndLoc,
15572 ReductionIdScopeSpec, ReductionId,
15573 UnresolvedReductions, RD))
15574 return nullptr;
15575
15576 return OMPTaskReductionClause::Create(
15577 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15578 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15579 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15580 buildPreInits(Context, RD.ExprCaptures),
15581 buildPostUpdate(*this, RD.ExprPostUpdates));
15582}
15583
15584OMPClause *Sema::ActOnOpenMPInReductionClause(
15585 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15586 SourceLocation ColonLoc, SourceLocation EndLoc,
15587 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15588 ArrayRef<Expr *> UnresolvedReductions) {
15589 ReductionData RD(VarList.size());
15590 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
15591 StartLoc, LParenLoc, ColonLoc, EndLoc,
15592 ReductionIdScopeSpec, ReductionId,
15593 UnresolvedReductions, RD))
15594 return nullptr;
15595
15596 return OMPInReductionClause::Create(
15597 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15598 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15599 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15600 buildPreInits(Context, RD.ExprCaptures),
15601 buildPostUpdate(*this, RD.ExprPostUpdates));
15602}
15603
15604bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15605 SourceLocation LinLoc) {
15606 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15607 LinKind == OMPC_LINEAR_unknown) {
15608 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15609 return true;
15610 }
15611 return false;
15612}
15613
15614bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15615 OpenMPLinearClauseKind LinKind, QualType Type,
15616 bool IsDeclareSimd) {
15617 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15618 // A variable must not have an incomplete type or a reference type.
15619 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15620 return true;
15621 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15622 !Type->isReferenceType()) {
15623 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15624 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15625 return true;
15626 }
15627 Type = Type.getNonReferenceType();
15628
15629 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15630 // A variable that is privatized must not have a const-qualified type
15631 // unless it is of class type with a mutable member. This restriction does
15632 // not apply to the firstprivate clause, nor to the linear clause on
15633 // declarative directives (like declare simd).
15634 if (!IsDeclareSimd &&
15635 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15636 return true;
15637
15638 // A list item must be of integral or pointer type.
15639 Type = Type.getUnqualifiedType().getCanonicalType();
15640 const auto *Ty = Type.getTypePtrOrNull();
15641 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15642 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15643 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15644 if (D) {
15645 bool IsDecl =
15646 !VD ||
15647 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15648 Diag(D->getLocation(),
15649 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15650 << D;
15651 }
15652 return true;
15653 }
15654 return false;
15655}
15656
15657OMPClause *Sema::ActOnOpenMPLinearClause(
15658 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15659 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15660 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15661 SmallVector<Expr *, 8> Vars;
15662 SmallVector<Expr *, 8> Privates;
15663 SmallVector<Expr *, 8> Inits;
15664 SmallVector<Decl *, 4> ExprCaptures;
15665 SmallVector<Expr *, 4> ExprPostUpdates;
15666 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15667 LinKind = OMPC_LINEAR_val;
15668 for (Expr *RefExpr : VarList) {
15669 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 15669, __PRETTY_FUNCTION__))
;
15670 SourceLocation ELoc;
15671 SourceRange ERange;
15672 Expr *SimpleRefExpr = RefExpr;
15673 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15674 if (Res.second) {
15675 // It will be analyzed later.
15676 Vars.push_back(RefExpr);
15677 Privates.push_back(nullptr);
15678 Inits.push_back(nullptr);
15679 }
15680 ValueDecl *D = Res.first;
15681 if (!D)
15682 continue;
15683
15684 QualType Type = D->getType();
15685 auto *VD = dyn_cast<VarDecl>(D);
15686
15687 // OpenMP [2.14.3.7, linear clause]
15688 // A list-item cannot appear in more than one linear clause.
15689 // A list-item that appears in a linear clause cannot appear in any
15690 // other data-sharing attribute clause.
15691 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15692 if (DVar.RefExpr) {
15693 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15694 << getOpenMPClauseName(OMPC_linear);
15695 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15696 continue;
15697 }
15698
15699 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15700 continue;
15701 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15702
15703 // Build private copy of original var.
15704 VarDecl *Private =
15705 buildVarDecl(*this, ELoc, Type, D->getName(),
15706 D->hasAttrs() ? &D->getAttrs() : nullptr,
15707 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15708 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15709 // Build var to save initial value.
15710 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15711 Expr *InitExpr;
15712 DeclRefExpr *Ref = nullptr;
15713 if (!VD && !CurContext->isDependentContext()) {
15714 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15715 if (!isOpenMPCapturedDecl(D)) {
15716 ExprCaptures.push_back(Ref->getDecl());
15717 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15718 ExprResult RefRes = DefaultLvalueConversion(Ref);
15719 if (!RefRes.isUsable())
15720 continue;
15721 ExprResult PostUpdateRes =
15722 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
15723 SimpleRefExpr, RefRes.get());
15724 if (!PostUpdateRes.isUsable())
15725 continue;
15726 ExprPostUpdates.push_back(
15727 IgnoredValueConversions(PostUpdateRes.get()).get());
15728 }
15729 }
15730 }
15731 if (LinKind == OMPC_LINEAR_uval)
15732 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15733 else
15734 InitExpr = VD ? SimpleRefExpr : Ref;
15735 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15736 /*DirectInit=*/false);
15737 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15738
15739 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15740 Vars.push_back((VD || CurContext->isDependentContext())
15741 ? RefExpr->IgnoreParens()
15742 : Ref);
15743 Privates.push_back(PrivateRef);
15744 Inits.push_back(InitRef);
15745 }
15746
15747 if (Vars.empty())
15748 return nullptr;
15749
15750 Expr *StepExpr = Step;
15751 Expr *CalcStepExpr = nullptr;
15752 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15753 !Step->isInstantiationDependent() &&
15754 !Step->containsUnexpandedParameterPack()) {
15755 SourceLocation StepLoc = Step->getBeginLoc();
15756 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15757 if (Val.isInvalid())
15758 return nullptr;
15759 StepExpr = Val.get();
15760
15761 // Build var to save the step value.
15762 VarDecl *SaveVar =
15763 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15764 ExprResult SaveRef =
15765 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15766 ExprResult CalcStep =
15767 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15768 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15769
15770 // Warn about zero linear step (it would be probably better specified as
15771 // making corresponding variables 'const').
15772 if (Optional<llvm::APSInt> Result =
15773 StepExpr->getIntegerConstantExpr(Context)) {
15774 if (!Result->isNegative() && !Result->isStrictlyPositive())
15775 Diag(StepLoc, diag::warn_omp_linear_step_zero)
15776 << Vars[0] << (Vars.size() > 1);
15777 } else if (CalcStep.isUsable()) {
15778 // Calculate the step beforehand instead of doing this on each iteration.
15779 // (This is not used if the number of iterations may be kfold-ed).
15780 CalcStepExpr = CalcStep.get();
15781 }
15782 }
15783
15784 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15785 ColonLoc, EndLoc, Vars, Privates, Inits,
15786 StepExpr, CalcStepExpr,
15787 buildPreInits(Context, ExprCaptures),
15788 buildPostUpdate(*this, ExprPostUpdates));
15789}
15790
15791static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15792 Expr *NumIterations, Sema &SemaRef,
15793 Scope *S, DSAStackTy *Stack) {
15794 // Walk the vars and build update/final expressions for the CodeGen.
15795 SmallVector<Expr *, 8> Updates;
15796 SmallVector<Expr *, 8> Finals;
15797 SmallVector<Expr *, 8> UsedExprs;
15798 Expr *Step = Clause.getStep();
15799 Expr *CalcStep = Clause.getCalcStep();
15800 // OpenMP [2.14.3.7, linear clause]
15801 // If linear-step is not specified it is assumed to be 1.
15802 if (!Step)
15803 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15804 else if (CalcStep)
15805 Step = cast<BinaryOperator>(CalcStep)->getLHS();
15806 bool HasErrors = false;
15807 auto CurInit = Clause.inits().begin();
15808 auto CurPrivate = Clause.privates().begin();
15809 OpenMPLinearClauseKind LinKind = Clause.getModifier();
15810 for (Expr *RefExpr : Clause.varlists()) {
15811 SourceLocation ELoc;
15812 SourceRange ERange;
15813 Expr *SimpleRefExpr = RefExpr;
15814 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15815 ValueDecl *D = Res.first;
15816 if (Res.second || !D) {
15817 Updates.push_back(nullptr);
15818 Finals.push_back(nullptr);
15819 HasErrors = true;
15820 continue;
15821 }
15822 auto &&Info = Stack->isLoopControlVariable(D);
15823 // OpenMP [2.15.11, distribute simd Construct]
15824 // A list item may not appear in a linear clause, unless it is the loop
15825 // iteration variable.
15826 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15827 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15828 SemaRef.Diag(ELoc,
15829 diag::err_omp_linear_distribute_var_non_loop_iteration);
15830 Updates.push_back(nullptr);
15831 Finals.push_back(nullptr);
15832 HasErrors = true;
15833 continue;
15834 }
15835 Expr *InitExpr = *CurInit;
15836
15837 // Build privatized reference to the current linear var.
15838 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15839 Expr *CapturedRef;
15840 if (LinKind == OMPC_LINEAR_uval)
15841 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15842 else
15843 CapturedRef =
15844 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15845 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15846 /*RefersToCapture=*/true);
15847
15848 // Build update: Var = InitExpr + IV * Step
15849 ExprResult Update;
15850 if (!Info.first)
15851 Update = buildCounterUpdate(
15852 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15853 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15854 else
15855 Update = *CurPrivate;
15856 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15857 /*DiscardedValue*/ false);
15858
15859 // Build final: Var = InitExpr + NumIterations * Step
15860 ExprResult Final;
15861 if (!Info.first)
15862 Final =
15863 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
15864 InitExpr, NumIterations, Step, /*Subtract=*/false,
15865 /*IsNonRectangularLB=*/false);
15866 else
15867 Final = *CurPrivate;
15868 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
15869 /*DiscardedValue*/ false);
15870
15871 if (!Update.isUsable() || !Final.isUsable()) {
15872 Updates.push_back(nullptr);
15873 Finals.push_back(nullptr);
15874 UsedExprs.push_back(nullptr);
15875 HasErrors = true;
15876 } else {
15877 Updates.push_back(Update.get());
15878 Finals.push_back(Final.get());
15879 if (!Info.first)
15880 UsedExprs.push_back(SimpleRefExpr);
15881 }
15882 ++CurInit;
15883 ++CurPrivate;
15884 }
15885 if (Expr *S = Clause.getStep())
15886 UsedExprs.push_back(S);
15887 // Fill the remaining part with the nullptr.
15888 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
15889 Clause.setUpdates(Updates);
15890 Clause.setFinals(Finals);
15891 Clause.setUsedExprs(UsedExprs);
15892 return HasErrors;
15893}
15894
15895OMPClause *Sema::ActOnOpenMPAlignedClause(
15896 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
15897 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15898 SmallVector<Expr *, 8> Vars;
15899 for (Expr *RefExpr : VarList) {
15900 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 15900, __PRETTY_FUNCTION__))
;
15901 SourceLocation ELoc;
15902 SourceRange ERange;
15903 Expr *SimpleRefExpr = RefExpr;
15904 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15905 if (Res.second) {
15906 // It will be analyzed later.
15907 Vars.push_back(RefExpr);
15908 }
15909 ValueDecl *D = Res.first;
15910 if (!D)
15911 continue;
15912
15913 QualType QType = D->getType();
15914 auto *VD = dyn_cast<VarDecl>(D);
15915
15916 // OpenMP [2.8.1, simd construct, Restrictions]
15917 // The type of list items appearing in the aligned clause must be
15918 // array, pointer, reference to array, or reference to pointer.
15919 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15920 const Type *Ty = QType.getTypePtrOrNull();
15921 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
15922 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
15923 << QType << getLangOpts().CPlusPlus << ERange;
15924 bool IsDecl =
15925 !VD ||
15926 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15927 Diag(D->getLocation(),
15928 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15929 << D;
15930 continue;
15931 }
15932
15933 // OpenMP [2.8.1, simd construct, Restrictions]
15934 // A list-item cannot appear in more than one aligned clause.
15935 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
15936 Diag(ELoc, diag::err_omp_used_in_clause_twice)
15937 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
15938 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
15939 << getOpenMPClauseName(OMPC_aligned);
15940 continue;
15941 }
15942
15943 DeclRefExpr *Ref = nullptr;
15944 if (!VD && isOpenMPCapturedDecl(D))
15945 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15946 Vars.push_back(DefaultFunctionArrayConversion(
15947 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
15948 .get());
15949 }
15950
15951 // OpenMP [2.8.1, simd construct, Description]
15952 // The parameter of the aligned clause, alignment, must be a constant
15953 // positive integer expression.
15954 // If no optional parameter is specified, implementation-defined default
15955 // alignments for SIMD instructions on the target platforms are assumed.
15956 if (Alignment != nullptr) {
15957 ExprResult AlignResult =
15958 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
15959 if (AlignResult.isInvalid())
15960 return nullptr;
15961 Alignment = AlignResult.get();
15962 }
15963 if (Vars.empty())
15964 return nullptr;
15965
15966 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
15967 EndLoc, Vars, Alignment);
15968}
15969
15970OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
15971 SourceLocation StartLoc,
15972 SourceLocation LParenLoc,
15973 SourceLocation EndLoc) {
15974 SmallVector<Expr *, 8> Vars;
15975 SmallVector<Expr *, 8> SrcExprs;
15976 SmallVector<Expr *, 8> DstExprs;
15977 SmallVector<Expr *, 8> AssignmentOps;
15978 for (Expr *RefExpr : VarList) {
15979 assert(RefExpr && "NULL expr in OpenMP copyin clause.")((RefExpr && "NULL expr in OpenMP copyin clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 15979, __PRETTY_FUNCTION__))
;
15980 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
15981 // It will be analyzed later.
15982 Vars.push_back(RefExpr);
15983 SrcExprs.push_back(nullptr);
15984 DstExprs.push_back(nullptr);
15985 AssignmentOps.push_back(nullptr);
15986 continue;
15987 }
15988
15989 SourceLocation ELoc = RefExpr->getExprLoc();
15990 // OpenMP [2.1, C/C++]
15991 // A list item is a variable name.
15992 // OpenMP [2.14.4.1, Restrictions, p.1]
15993 // A list item that appears in a copyin clause must be threadprivate.
15994 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
15995 if (!DE || !isa<VarDecl>(DE->getDecl())) {
15996 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
15997 << 0 << RefExpr->getSourceRange();
15998 continue;
15999 }
16000
16001 Decl *D = DE->getDecl();
16002 auto *VD = cast<VarDecl>(D);
16003
16004 QualType Type = VD->getType();
16005 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
16006 // It will be analyzed later.
16007 Vars.push_back(DE);
16008 SrcExprs.push_back(nullptr);
16009 DstExprs.push_back(nullptr);
16010 AssignmentOps.push_back(nullptr);
16011 continue;
16012 }
16013
16014 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
16015 // A list item that appears in a copyin clause must be threadprivate.
16016 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16017 Diag(ELoc, diag::err_omp_required_access)
16018 << getOpenMPClauseName(OMPC_copyin)
16019 << getOpenMPDirectiveName(OMPD_threadprivate);
16020 continue;
16021 }
16022
16023 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16024 // A variable of class type (or array thereof) that appears in a
16025 // copyin clause requires an accessible, unambiguous copy assignment
16026 // operator for the class type.
16027 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16028 VarDecl *SrcVD =
16029 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16030 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16031 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16032 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16033 VarDecl *DstVD =
16034 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16035 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16036 DeclRefExpr *PseudoDstExpr =
16037 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16038 // For arrays generate assignment operation for single element and replace
16039 // it by the original array element in CodeGen.
16040 ExprResult AssignmentOp =
16041 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16042 PseudoSrcExpr);
16043 if (AssignmentOp.isInvalid())
16044 continue;
16045 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16046 /*DiscardedValue*/ false);
16047 if (AssignmentOp.isInvalid())
16048 continue;
16049
16050 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
16051 Vars.push_back(DE);
16052 SrcExprs.push_back(PseudoSrcExpr);
16053 DstExprs.push_back(PseudoDstExpr);
16054 AssignmentOps.push_back(AssignmentOp.get());
16055 }
16056
16057 if (Vars.empty())
16058 return nullptr;
16059
16060 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16061 SrcExprs, DstExprs, AssignmentOps);
16062}
16063
16064OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16065 SourceLocation StartLoc,
16066 SourceLocation LParenLoc,
16067 SourceLocation EndLoc) {
16068 SmallVector<Expr *, 8> Vars;
16069 SmallVector<Expr *, 8> SrcExprs;
16070 SmallVector<Expr *, 8> DstExprs;
16071 SmallVector<Expr *, 8> AssignmentOps;
16072 for (Expr *RefExpr : VarList) {
16073 assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16073, __PRETTY_FUNCTION__))
;
16074 SourceLocation ELoc;
16075 SourceRange ERange;
16076 Expr *SimpleRefExpr = RefExpr;
16077 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16078 if (Res.second) {
16079 // It will be analyzed later.
16080 Vars.push_back(RefExpr);
16081 SrcExprs.push_back(nullptr);
16082 DstExprs.push_back(nullptr);
16083 AssignmentOps.push_back(nullptr);
16084 }
16085 ValueDecl *D = Res.first;
16086 if (!D)
16087 continue;
16088
16089 QualType Type = D->getType();
16090 auto *VD = dyn_cast<VarDecl>(D);
16091
16092 // OpenMP [2.14.4.2, Restrictions, p.2]
16093 // A list item that appears in a copyprivate clause may not appear in a
16094 // private or firstprivate clause on the single construct.
16095 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
16096 DSAStackTy::DSAVarData DVar =
16097 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
16098 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16099 DVar.RefExpr) {
16100 Diag(ELoc, diag::err_omp_wrong_dsa)
16101 << getOpenMPClauseName(DVar.CKind)
16102 << getOpenMPClauseName(OMPC_copyprivate);
16103 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16104 continue;
16105 }
16106
16107 // OpenMP [2.11.4.2, Restrictions, p.1]
16108 // All list items that appear in a copyprivate clause must be either
16109 // threadprivate or private in the enclosing context.
16110 if (DVar.CKind == OMPC_unknown) {
16111 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
16112 if (DVar.CKind == OMPC_shared) {
16113 Diag(ELoc, diag::err_omp_required_access)
16114 << getOpenMPClauseName(OMPC_copyprivate)
16115 << "threadprivate or private in the enclosing context";
16116 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
16117 continue;
16118 }
16119 }
16120 }
16121
16122 // Variably modified types are not supported.
16123 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16124 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16125 << getOpenMPClauseName(OMPC_copyprivate) << Type
16126 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
16127 bool IsDecl =
16128 !VD ||
16129 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16130 Diag(D->getLocation(),
16131 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16132 << D;
16133 continue;
16134 }
16135
16136 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16137 // A variable of class type (or array thereof) that appears in a
16138 // copyin clause requires an accessible, unambiguous copy assignment
16139 // operator for the class type.
16140 Type = Context.getBaseElementType(Type.getNonReferenceType())
16141 .getUnqualifiedType();
16142 VarDecl *SrcVD =
16143 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16144 D->hasAttrs() ? &D->getAttrs() : nullptr);
16145 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16146 VarDecl *DstVD =
16147 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16148 D->hasAttrs() ? &D->getAttrs() : nullptr);
16149 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16150 ExprResult AssignmentOp = BuildBinOp(
16151 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16152 if (AssignmentOp.isInvalid())
16153 continue;
16154 AssignmentOp =
16155 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16156 if (AssignmentOp.isInvalid())
16157 continue;
16158
16159 // No need to mark vars as copyprivate, they are already threadprivate or
16160 // implicitly private.
16161 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16161, __PRETTY_FUNCTION__))
;
16162 Vars.push_back(
16163 VD ? RefExpr->IgnoreParens()
16164 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16165 SrcExprs.push_back(PseudoSrcExpr);
16166 DstExprs.push_back(PseudoDstExpr);
16167 AssignmentOps.push_back(AssignmentOp.get());
16168 }
16169
16170 if (Vars.empty())
16171 return nullptr;
16172
16173 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16174 Vars, SrcExprs, DstExprs, AssignmentOps);
16175}
16176
16177OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16178 SourceLocation StartLoc,
16179 SourceLocation LParenLoc,
16180 SourceLocation EndLoc) {
16181 if (VarList.empty())
16182 return nullptr;
16183
16184 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16185}
16186
16187/// Tries to find omp_depend_t. type.
16188static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16189 bool Diagnose = true) {
16190 QualType OMPDependT = Stack->getOMPDependT();
16191 if (!OMPDependT.isNull())
16192 return true;
16193 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16194 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16195 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16196 if (Diagnose)
16197 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16198 return false;
16199 }
16200 Stack->setOMPDependT(PT.get());
16201 return true;
16202}
16203
16204OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16205 SourceLocation LParenLoc,
16206 SourceLocation EndLoc) {
16207 if (!Depobj)
16208 return nullptr;
16209
16210 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
16211
16212 // OpenMP 5.0, 2.17.10.1 depobj Construct
16213 // depobj is an lvalue expression of type omp_depend_t.
16214 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16215 !Depobj->isInstantiationDependent() &&
16216 !Depobj->containsUnexpandedParameterPack() &&
16217 (OMPDependTFound &&
16218 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
16219 /*CompareUnqualified=*/true))) {
16220 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16221 << 0 << Depobj->getType() << Depobj->getSourceRange();
16222 }
16223
16224 if (!Depobj->isLValue()) {
16225 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16226 << 1 << Depobj->getSourceRange();
16227 }
16228
16229 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16230}
16231
16232OMPClause *
16233Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16234 SourceLocation DepLoc, SourceLocation ColonLoc,
16235 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16236 SourceLocation LParenLoc, SourceLocation EndLoc) {
16237 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
16238 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16239 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16240 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16241 return nullptr;
16242 }
16243 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
16244 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16245 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16246 DepKind == OMPC_DEPEND_sink ||
16247 ((LangOpts.OpenMP < 50 ||
16248 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
16249 DepKind == OMPC_DEPEND_depobj))) {
16250 SmallVector<unsigned, 3> Except;
16251 Except.push_back(OMPC_DEPEND_source);
16252 Except.push_back(OMPC_DEPEND_sink);
16253 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
16254 Except.push_back(OMPC_DEPEND_depobj);
16255 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16256 ? "depend modifier(iterator) or "
16257 : "";
16258 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16259 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16260 /*Last=*/OMPC_DEPEND_unknown,
16261 Except)
16262 << getOpenMPClauseName(OMPC_depend);
16263 return nullptr;
16264 }
16265 if (DepModifier &&
16266 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16267 Diag(DepModifier->getExprLoc(),
16268 diag::err_omp_depend_sink_source_with_modifier);
16269 return nullptr;
16270 }
16271 if (DepModifier &&
16272 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16273 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16274
16275 SmallVector<Expr *, 8> Vars;
16276 DSAStackTy::OperatorOffsetTy OpsOffs;
16277 llvm::APSInt DepCounter(/*BitWidth=*/32);
16278 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16279 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16280 if (const Expr *OrderedCountExpr =
16281 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
16282 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16283 TotalDepCount.setIsUnsigned(/*Val=*/true);
16284 }
16285 }
16286 for (Expr *RefExpr : VarList) {
16287 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16287, __PRETTY_FUNCTION__))
;
16288 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16289 // It will be analyzed later.
16290 Vars.push_back(RefExpr);
16291 continue;
16292 }
16293
16294 SourceLocation ELoc = RefExpr->getExprLoc();
16295 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16296 if (DepKind == OMPC_DEPEND_sink) {
16297 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16298 DepCounter >= TotalDepCount) {
16299 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16300 continue;
16301 }
16302 ++DepCounter;
16303 // OpenMP [2.13.9, Summary]
16304 // depend(dependence-type : vec), where dependence-type is:
16305 // 'sink' and where vec is the iteration vector, which has the form:
16306 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16307 // where n is the value specified by the ordered clause in the loop
16308 // directive, xi denotes the loop iteration variable of the i-th nested
16309 // loop associated with the loop directive, and di is a constant
16310 // non-negative integer.
16311 if (CurContext->isDependentContext()) {
16312 // It will be analyzed later.
16313 Vars.push_back(RefExpr);
16314 continue;
16315 }
16316 SimpleExpr = SimpleExpr->IgnoreImplicit();
16317 OverloadedOperatorKind OOK = OO_None;
16318 SourceLocation OOLoc;
16319 Expr *LHS = SimpleExpr;
16320 Expr *RHS = nullptr;
16321 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16322 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16323 OOLoc = BO->getOperatorLoc();
16324 LHS = BO->getLHS()->IgnoreParenImpCasts();
16325 RHS = BO->getRHS()->IgnoreParenImpCasts();
16326 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16327 OOK = OCE->getOperator();
16328 OOLoc = OCE->getOperatorLoc();
16329 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16330 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16331 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16332 OOK = MCE->getMethodDecl()
16333 ->getNameInfo()
16334 .getName()
16335 .getCXXOverloadedOperator();
16336 OOLoc = MCE->getCallee()->getExprLoc();
16337 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16338 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16339 }
16340 SourceLocation ELoc;
16341 SourceRange ERange;
16342 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16343 if (Res.second) {
16344 // It will be analyzed later.
16345 Vars.push_back(RefExpr);
16346 }
16347 ValueDecl *D = Res.first;
16348 if (!D)
16349 continue;
16350
16351 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16352 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16353 continue;
16354 }
16355 if (RHS) {
16356 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16357 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16358 if (RHSRes.isInvalid())
16359 continue;
16360 }
16361 if (!CurContext->isDependentContext() &&
16362 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16363 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
16364 const ValueDecl *VD =
16365 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
16366 if (VD)
16367 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16368 << 1 << VD;
16369 else
16370 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16371 continue;
16372 }
16373 OpsOffs.emplace_back(RHS, OOK);
16374 } else {
16375 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16376 if (OMPDependTFound)
16377 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
16378 DepKind == OMPC_DEPEND_depobj);
16379 if (DepKind == OMPC_DEPEND_depobj) {
16380 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16381 // List items used in depend clauses with the depobj dependence type
16382 // must be expressions of the omp_depend_t type.
16383 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16384 !RefExpr->isInstantiationDependent() &&
16385 !RefExpr->containsUnexpandedParameterPack() &&
16386 (OMPDependTFound &&
16387 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
16388 RefExpr->getType()))) {
16389 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16390 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16391 continue;
16392 }
16393 if (!RefExpr->isLValue()) {
16394 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16395 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16396 continue;
16397 }
16398 } else {
16399 // OpenMP 5.0 [2.17.11, Restrictions]
16400 // List items used in depend clauses cannot be zero-length array
16401 // sections.
16402 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16403 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16404 if (OASE) {
16405 QualType BaseType =
16406 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16407 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16408 ExprTy = ATy->getElementType();
16409 else
16410 ExprTy = BaseType->getPointeeType();
16411 ExprTy = ExprTy.getNonReferenceType();
16412 const Expr *Length = OASE->getLength();
16413 Expr::EvalResult Result;
16414 if (Length && !Length->isValueDependent() &&
16415 Length->EvaluateAsInt(Result, Context) &&
16416 Result.Val.getInt().isNullValue()) {
16417 Diag(ELoc,
16418 diag::err_omp_depend_zero_length_array_section_not_allowed)
16419 << SimpleExpr->getSourceRange();
16420 continue;
16421 }
16422 }
16423
16424 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16425 // List items used in depend clauses with the in, out, inout or
16426 // mutexinoutset dependence types cannot be expressions of the
16427 // omp_depend_t type.
16428 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16429 !RefExpr->isInstantiationDependent() &&
16430 !RefExpr->containsUnexpandedParameterPack() &&
16431 (OMPDependTFound &&
16432 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16433 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16434 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16435 << RefExpr->getSourceRange();
16436 continue;
16437 }
16438
16439 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16440 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16441 (ASE && !ASE->getBase()->isTypeDependent() &&
16442 !ASE->getBase()
16443 ->getType()
16444 .getNonReferenceType()
16445 ->isPointerType() &&
16446 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16447 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16448 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16449 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16450 continue;
16451 }
16452
16453 ExprResult Res;
16454 {
16455 Sema::TentativeAnalysisScope Trap(*this);
16456 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16457 RefExpr->IgnoreParenImpCasts());
16458 }
16459 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16460 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16461 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16462 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16463 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16464 continue;
16465 }
16466 }
16467 }
16468 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16469 }
16470
16471 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16472 TotalDepCount > VarList.size() &&
16473 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
16474 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
16475 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16476 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
16477 }
16478 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16479 Vars.empty())
16480 return nullptr;
16481
16482 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16483 DepModifier, DepKind, DepLoc, ColonLoc,
16484 Vars, TotalDepCount.getZExtValue());
16485 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16486 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
16487 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
16488 return C;
16489}
16490
16491OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16492 Expr *Device, SourceLocation StartLoc,
16493 SourceLocation LParenLoc,
16494 SourceLocation ModifierLoc,
16495 SourceLocation EndLoc) {
16496 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16497, __PRETTY_FUNCTION__))
16497 "Unexpected device modifier in OpenMP < 50.")(((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
"Unexpected device modifier in OpenMP < 50.") ? static_cast
<void> (0) : __assert_fail ("(ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && \"Unexpected device modifier in OpenMP < 50.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16497, __PRETTY_FUNCTION__))
;
16498
16499 bool ErrorFound = false;
16500 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16501 std::string Values =
16502 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16503 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16504 << Values << getOpenMPClauseName(OMPC_device);
16505 ErrorFound = true;
16506 }
16507
16508 Expr *ValExpr = Device;
16509 Stmt *HelperValStmt = nullptr;
16510
16511 // OpenMP [2.9.1, Restrictions]
16512 // The device expression must evaluate to a non-negative integer value.
16513 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16514 /*StrictlyPositive=*/false) ||
16515 ErrorFound;
16516 if (ErrorFound)
16517 return nullptr;
16518
16519 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
16520 OpenMPDirectiveKind CaptureRegion =
16521 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16522 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16523 ValExpr = MakeFullExpr(ValExpr).get();
16524 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16525 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16526 HelperValStmt = buildPreInits(Context, Captures);
16527 }
16528
16529 return new (Context)
16530 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16531 LParenLoc, ModifierLoc, EndLoc);
16532}
16533
16534static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16535 DSAStackTy *Stack, QualType QTy,
16536 bool FullCheck = true) {
16537 NamedDecl *ND;
16538 if (QTy->isIncompleteType(&ND)) {
16539 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16540 return false;
16541 }
16542 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16543 !QTy.isTriviallyCopyableType(SemaRef.Context))
16544 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16545 return true;
16546}
16547
16548/// Return true if it can be proven that the provided array expression
16549/// (array section or array subscript) does NOT specify the whole size of the
16550/// array whose base type is \a BaseQTy.
16551static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16552 const Expr *E,
16553 QualType BaseQTy) {
16554 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16555
16556 // If this is an array subscript, it refers to the whole size if the size of
16557 // the dimension is constant and equals 1. Also, an array section assumes the
16558 // format of an array subscript if no colon is used.
16559 if (isa<ArraySubscriptExpr>(E) ||
16560 (OASE && OASE->getColonLocFirst().isInvalid())) {
16561 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16562 return ATy->getSize().getSExtValue() != 1;
16563 // Size can't be evaluated statically.
16564 return false;
16565 }
16566
16567 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16567, __PRETTY_FUNCTION__))
;
16568 const Expr *LowerBound = OASE->getLowerBound();
16569 const Expr *Length = OASE->getLength();
16570
16571 // If there is a lower bound that does not evaluates to zero, we are not
16572 // covering the whole dimension.
16573 if (LowerBound) {
16574 Expr::EvalResult Result;
16575 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16576 return false; // Can't get the integer value as a constant.
16577
16578 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16579 if (ConstLowerBound.getSExtValue())
16580 return true;
16581 }
16582
16583 // If we don't have a length we covering the whole dimension.
16584 if (!Length)
16585 return false;
16586
16587 // If the base is a pointer, we don't have a way to get the size of the
16588 // pointee.
16589 if (BaseQTy->isPointerType())
16590 return false;
16591
16592 // We can only check if the length is the same as the size of the dimension
16593 // if we have a constant array.
16594 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16595 if (!CATy)
16596 return false;
16597
16598 Expr::EvalResult Result;
16599 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16600 return false; // Can't get the integer value as a constant.
16601
16602 llvm::APSInt ConstLength = Result.Val.getInt();
16603 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16604}
16605
16606// Return true if it can be proven that the provided array expression (array
16607// section or array subscript) does NOT specify a single element of the array
16608// whose base type is \a BaseQTy.
16609static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16610 const Expr *E,
16611 QualType BaseQTy) {
16612 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16613
16614 // An array subscript always refer to a single element. Also, an array section
16615 // assumes the format of an array subscript if no colon is used.
16616 if (isa<ArraySubscriptExpr>(E) ||
16617 (OASE && OASE->getColonLocFirst().isInvalid()))
16618 return false;
16619
16620 assert(OASE && "Expecting array section if not an array subscript.")((OASE && "Expecting array section if not an array subscript."
) ? static_cast<void> (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16620, __PRETTY_FUNCTION__))
;
16621 const Expr *Length = OASE->getLength();
16622
16623 // If we don't have a length we have to check if the array has unitary size
16624 // for this dimension. Also, we should always expect a length if the base type
16625 // is pointer.
16626 if (!Length) {
16627 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16628 return ATy->getSize().getSExtValue() != 1;
16629 // We cannot assume anything.
16630 return false;
16631 }
16632
16633 // Check if the length evaluates to 1.
16634 Expr::EvalResult Result;
16635 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16636 return false; // Can't get the integer value as a constant.
16637
16638 llvm::APSInt ConstLength = Result.Val.getInt();
16639 return ConstLength.getSExtValue() != 1;
16640}
16641
16642// The base of elements of list in a map clause have to be either:
16643// - a reference to variable or field.
16644// - a member expression.
16645// - an array expression.
16646//
16647// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16648// reference to 'r'.
16649//
16650// If we have:
16651//
16652// struct SS {
16653// Bla S;
16654// foo() {
16655// #pragma omp target map (S.Arr[:12]);
16656// }
16657// }
16658//
16659// We want to retrieve the member expression 'this->S';
16660
16661// OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16662// If a list item is an array section, it must specify contiguous storage.
16663//
16664// For this restriction it is sufficient that we make sure only references
16665// to variables or fields and array expressions, and that no array sections
16666// exist except in the rightmost expression (unless they cover the whole
16667// dimension of the array). E.g. these would be invalid:
16668//
16669// r.ArrS[3:5].Arr[6:7]
16670//
16671// r.ArrS[3:5].x
16672//
16673// but these would be valid:
16674// r.ArrS[3].Arr[6:7]
16675//
16676// r.ArrS[3].x
16677namespace {
16678class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16679 Sema &SemaRef;
16680 OpenMPClauseKind CKind = OMPC_unknown;
16681 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16682 bool NoDiagnose = false;
16683 const Expr *RelevantExpr = nullptr;
16684 bool AllowUnitySizeArraySection = true;
16685 bool AllowWholeSizeArraySection = true;
16686 SourceLocation ELoc;
16687 SourceRange ERange;
16688
16689 void emitErrorMsg() {
16690 // If nothing else worked, this is not a valid map clause expression.
16691 if (SemaRef.getLangOpts().OpenMP < 50) {
16692 SemaRef.Diag(ELoc,
16693 diag::err_omp_expected_named_var_member_or_array_expression)
16694 << ERange;
16695 } else {
16696 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16697 << getOpenMPClauseName(CKind) << ERange;
16698 }
16699 }
16700
16701public:
16702 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16703 if (!isa<VarDecl>(DRE->getDecl())) {
16704 emitErrorMsg();
16705 return false;
16706 }
16707 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16707, __PRETTY_FUNCTION__))
;
16708 RelevantExpr = DRE;
16709 // Record the component.
16710 Components.emplace_back(DRE, DRE->getDecl());
16711 return true;
16712 }
16713
16714 bool VisitMemberExpr(MemberExpr *ME) {
16715 Expr *E = ME;
16716 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16717
16718 if (isa<CXXThisExpr>(BaseE)) {
16719 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16719, __PRETTY_FUNCTION__))
;
16720 // We found a base expression: this->Val.
16721 RelevantExpr = ME;
16722 } else {
16723 E = BaseE;
16724 }
16725
16726 if (!isa<FieldDecl>(ME->getMemberDecl())) {
16727 if (!NoDiagnose) {
16728 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16729 << ME->getSourceRange();
16730 return false;
16731 }
16732 if (RelevantExpr)
16733 return false;
16734 return Visit(E);
16735 }
16736
16737 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16738
16739 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16740 // A bit-field cannot appear in a map clause.
16741 //
16742 if (FD->isBitField()) {
16743 if (!NoDiagnose) {
16744 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16745 << ME->getSourceRange() << getOpenMPClauseName(CKind);
16746 return false;
16747 }
16748 if (RelevantExpr)
16749 return false;
16750 return Visit(E);
16751 }
16752
16753 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16754 // If the type of a list item is a reference to a type T then the type
16755 // will be considered to be T for all purposes of this clause.
16756 QualType CurType = BaseE->getType().getNonReferenceType();
16757
16758 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16759 // A list item cannot be a variable that is a member of a structure with
16760 // a union type.
16761 //
16762 if (CurType->isUnionType()) {
16763 if (!NoDiagnose) {
16764 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16765 << ME->getSourceRange();
16766 return false;
16767 }
16768 return RelevantExpr || Visit(E);
16769 }
16770
16771 // If we got a member expression, we should not expect any array section
16772 // before that:
16773 //
16774 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16775 // If a list item is an element of a structure, only the rightmost symbol
16776 // of the variable reference can be an array section.
16777 //
16778 AllowUnitySizeArraySection = false;
16779 AllowWholeSizeArraySection = false;
16780
16781 // Record the component.
16782 Components.emplace_back(ME, FD);
16783 return RelevantExpr || Visit(E);
16784 }
16785
16786 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16787 Expr *E = AE->getBase()->IgnoreParenImpCasts();
16788
16789 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16790 if (!NoDiagnose) {
16791 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16792 << 0 << AE->getSourceRange();
16793 return false;
16794 }
16795 return RelevantExpr || Visit(E);
16796 }
16797
16798 // If we got an array subscript that express the whole dimension we
16799 // can have any array expressions before. If it only expressing part of
16800 // the dimension, we can only have unitary-size array expressions.
16801 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16802 E->getType()))
16803 AllowWholeSizeArraySection = false;
16804
16805 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16806 Expr::EvalResult Result;
16807 if (!AE->getIdx()->isValueDependent() &&
16808 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16809 !Result.Val.getInt().isNullValue()) {
16810 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16811 diag::err_omp_invalid_map_this_expr);
16812 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16813 diag::note_omp_invalid_subscript_on_this_ptr_map);
16814 }
16815 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16815, __PRETTY_FUNCTION__))
;
16816 RelevantExpr = TE;
16817 }
16818
16819 // Record the component - we don't have any declaration associated.
16820 Components.emplace_back(AE, nullptr);
16821
16822 return RelevantExpr || Visit(E);
16823 }
16824
16825 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16826 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")((!NoDiagnose && "Array sections cannot be implicitly mapped."
) ? static_cast<void> (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16826, __PRETTY_FUNCTION__))
;
16827 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16828 QualType CurType =
16829 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16830
16831 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16832 // If the type of a list item is a reference to a type T then the type
16833 // will be considered to be T for all purposes of this clause.
16834 if (CurType->isReferenceType())
16835 CurType = CurType->getPointeeType();
16836
16837 bool IsPointer = CurType->isAnyPointerType();
16838
16839 if (!IsPointer && !CurType->isArrayType()) {
16840 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16841 << 0 << OASE->getSourceRange();
16842 return false;
16843 }
16844
16845 bool NotWhole =
16846 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16847 bool NotUnity =
16848 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16849
16850 if (AllowWholeSizeArraySection) {
16851 // Any array section is currently allowed. Allowing a whole size array
16852 // section implies allowing a unity array section as well.
16853 //
16854 // If this array section refers to the whole dimension we can still
16855 // accept other array sections before this one, except if the base is a
16856 // pointer. Otherwise, only unitary sections are accepted.
16857 if (NotWhole || IsPointer)
16858 AllowWholeSizeArraySection = false;
16859 } else if (AllowUnitySizeArraySection && NotUnity) {
16860 // A unity or whole array section is not allowed and that is not
16861 // compatible with the properties of the current array section.
16862 SemaRef.Diag(
16863 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
16864 << OASE->getSourceRange();
16865 return false;
16866 }
16867
16868 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
16869 Expr::EvalResult ResultR;
16870 Expr::EvalResult ResultL;
16871 if (!OASE->getLength()->isValueDependent() &&
16872 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
16873 !ResultR.Val.getInt().isOneValue()) {
16874 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16875 diag::err_omp_invalid_map_this_expr);
16876 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16877 diag::note_omp_invalid_length_on_this_ptr_mapping);
16878 }
16879 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
16880 OASE->getLowerBound()->EvaluateAsInt(ResultL,
16881 SemaRef.getASTContext()) &&
16882 !ResultL.Val.getInt().isNullValue()) {
16883 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16884 diag::err_omp_invalid_map_this_expr);
16885 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16886 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
16887 }
16888 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16888, __PRETTY_FUNCTION__))
;
16889 RelevantExpr = TE;
16890 }
16891
16892 // Record the component - we don't have any declaration associated.
16893 Components.emplace_back(OASE, nullptr);
16894 return RelevantExpr || Visit(E);
16895 }
16896 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
16897 Expr *Base = E->getBase();
16898
16899 // Record the component - we don't have any declaration associated.
16900 Components.emplace_back(E, nullptr);
16901
16902 return Visit(Base->IgnoreParenImpCasts());
16903 }
16904
16905 bool VisitUnaryOperator(UnaryOperator *UO) {
16906 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
16907 UO->getOpcode() != UO_Deref) {
16908 emitErrorMsg();
16909 return false;
16910 }
16911 if (!RelevantExpr) {
16912 // Record the component if haven't found base decl.
16913 Components.emplace_back(UO, nullptr);
16914 }
16915 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
16916 }
16917 bool VisitBinaryOperator(BinaryOperator *BO) {
16918 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
16919 emitErrorMsg();
16920 return false;
16921 }
16922
16923 // Pointer arithmetic is the only thing we expect to happen here so after we
16924 // make sure the binary operator is a pointer type, the we only thing need
16925 // to to is to visit the subtree that has the same type as root (so that we
16926 // know the other subtree is just an offset)
16927 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
16928 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
16929 Components.emplace_back(BO, nullptr);
16930 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16932, __PRETTY_FUNCTION__))
16931 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16932, __PRETTY_FUNCTION__))
16932 "Either LHS or RHS have base decl inside")(((LE->getType().getTypePtr() == BO->getType().getTypePtr
() || RE->getType().getTypePtr() == BO->getType().getTypePtr
()) && "Either LHS or RHS have base decl inside") ? static_cast
<void> (0) : __assert_fail ("(LE->getType().getTypePtr() == BO->getType().getTypePtr() || RE->getType().getTypePtr() == BO->getType().getTypePtr()) && \"Either LHS or RHS have base decl inside\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16932, __PRETTY_FUNCTION__))
;
16933 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
16934 return RelevantExpr || Visit(LE);
16935 return RelevantExpr || Visit(RE);
16936 }
16937 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
16938 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr")((!RelevantExpr && "RelevantExpr is expected to be nullptr"
) ? static_cast<void> (0) : __assert_fail ("!RelevantExpr && \"RelevantExpr is expected to be nullptr\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16938, __PRETTY_FUNCTION__))
;
16939 RelevantExpr = CTE;
16940 Components.emplace_back(CTE, nullptr);
16941 return true;
16942 }
16943 bool VisitStmt(Stmt *) {
16944 emitErrorMsg();
16945 return false;
16946 }
16947 const Expr *getFoundBase() const {
16948 return RelevantExpr;
16949 }
16950 explicit MapBaseChecker(
16951 Sema &SemaRef, OpenMPClauseKind CKind,
16952 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
16953 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
16954 : SemaRef(SemaRef), CKind(CKind), Components(Components),
16955 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
16956};
16957} // namespace
16958
16959/// Return the expression of the base of the mappable expression or null if it
16960/// cannot be determined and do all the necessary checks to see if the expression
16961/// is valid as a standalone mappable expression. In the process, record all the
16962/// components of the expression.
16963static const Expr *checkMapClauseExpressionBase(
16964 Sema &SemaRef, Expr *E,
16965 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
16966 OpenMPClauseKind CKind, bool NoDiagnose) {
16967 SourceLocation ELoc = E->getExprLoc();
16968 SourceRange ERange = E->getSourceRange();
16969 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
16970 ERange);
16971 if (Checker.Visit(E->IgnoreParens()))
16972 return Checker.getFoundBase();
16973 return nullptr;
16974}
16975
16976// Return true if expression E associated with value VD has conflicts with other
16977// map information.
16978static bool checkMapConflicts(
16979 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
16980 bool CurrentRegionOnly,
16981 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
16982 OpenMPClauseKind CKind) {
16983 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16983, __PRETTY_FUNCTION__))
;
16984 SourceLocation ELoc = E->getExprLoc();
16985 SourceRange ERange = E->getSourceRange();
16986
16987 // In order to easily check the conflicts we need to match each component of
16988 // the expression under test with the components of the expressions that are
16989 // already in the stack.
16990
16991 assert(!CurComponents.empty() && "Map clause expression with no components!")((!CurComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16991, __PRETTY_FUNCTION__))
;
16992 assert(CurComponents.back().getAssociatedDeclaration() == VD &&((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16993, __PRETTY_FUNCTION__))
16993 "Map clause expression with unexpected base!")((CurComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 16993, __PRETTY_FUNCTION__))
;
16994
16995 // Variables to help detecting enclosing problems in data environment nests.
16996 bool IsEnclosedByDataEnvironmentExpr = false;
16997 const Expr *EnclosingExpr = nullptr;
16998
16999 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
17000 VD, CurrentRegionOnly,
17001 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
17002 ERange, CKind, &EnclosingExpr,
17003 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
17004 StackComponents,
17005 OpenMPClauseKind) {
17006 assert(!StackComponents.empty() &&((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17007, __PRETTY_FUNCTION__))
17007 "Map clause expression with no components!")((!StackComponents.empty() && "Map clause expression with no components!"
) ? static_cast<void> (0) : __assert_fail ("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17007, __PRETTY_FUNCTION__))
;
17008 assert(StackComponents.back().getAssociatedDeclaration() == VD &&((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17009, __PRETTY_FUNCTION__))
17009 "Map clause expression with unexpected base!")((StackComponents.back().getAssociatedDeclaration() == VD &&
"Map clause expression with unexpected base!") ? static_cast
<void> (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17009, __PRETTY_FUNCTION__))
;
17010 (void)VD;
17011
17012 // The whole expression in the stack.
17013 const Expr *RE = StackComponents.front().getAssociatedExpression();
17014
17015 // Expressions must start from the same base. Here we detect at which
17016 // point both expressions diverge from each other and see if we can
17017 // detect if the memory referred to both expressions is contiguous and
17018 // do not overlap.
17019 auto CI = CurComponents.rbegin();
17020 auto CE = CurComponents.rend();
17021 auto SI = StackComponents.rbegin();
17022 auto SE = StackComponents.rend();
17023 for (; CI != CE && SI != SE; ++CI, ++SI) {
17024
17025 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17026 // At most one list item can be an array item derived from a given
17027 // variable in map clauses of the same construct.
17028 if (CurrentRegionOnly &&
17029 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17030 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17031 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17032 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17033 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17034 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17035 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17036 diag::err_omp_multiple_array_items_in_map_clause)
17037 << CI->getAssociatedExpression()->getSourceRange();
17038 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17039 diag::note_used_here)
17040 << SI->getAssociatedExpression()->getSourceRange();
17041 return true;
17042 }
17043
17044 // Do both expressions have the same kind?
17045 if (CI->getAssociatedExpression()->getStmtClass() !=
17046 SI->getAssociatedExpression()->getStmtClass())
17047 break;
17048
17049 // Are we dealing with different variables/fields?
17050 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17051 break;
17052 }
17053 // Check if the extra components of the expressions in the enclosing
17054 // data environment are redundant for the current base declaration.
17055 // If they are, the maps completely overlap, which is legal.
17056 for (; SI != SE; ++SI) {
17057 QualType Type;
17058 if (const auto *ASE =
17059 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17060 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17061 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17062 SI->getAssociatedExpression())) {
17063 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17064 Type =
17065 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17066 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17067 SI->getAssociatedExpression())) {
17068 Type = OASE->getBase()->getType()->getPointeeType();
17069 }
17070 if (Type.isNull() || Type->isAnyPointerType() ||
17071 checkArrayExpressionDoesNotReferToWholeSize(
17072 SemaRef, SI->getAssociatedExpression(), Type))
17073 break;
17074 }
17075
17076 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17077 // List items of map clauses in the same construct must not share
17078 // original storage.
17079 //
17080 // If the expressions are exactly the same or one is a subset of the
17081 // other, it means they are sharing storage.
17082 if (CI == CE && SI == SE) {
17083 if (CurrentRegionOnly) {
17084 if (CKind == OMPC_map) {
17085 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17086 } else {
17087 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17087, __PRETTY_FUNCTION__))
;
17088 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17089 << ERange;
17090 }
17091 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17092 << RE->getSourceRange();
17093 return true;
17094 }
17095 // If we find the same expression in the enclosing data environment,
17096 // that is legal.
17097 IsEnclosedByDataEnvironmentExpr = true;
17098 return false;
17099 }
17100
17101 QualType DerivedType =
17102 std::prev(CI)->getAssociatedDeclaration()->getType();
17103 SourceLocation DerivedLoc =
17104 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17105
17106 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17107 // If the type of a list item is a reference to a type T then the type
17108 // will be considered to be T for all purposes of this clause.
17109 DerivedType = DerivedType.getNonReferenceType();
17110
17111 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17112 // A variable for which the type is pointer and an array section
17113 // derived from that variable must not appear as list items of map
17114 // clauses of the same construct.
17115 //
17116 // Also, cover one of the cases in:
17117 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17118 // If any part of the original storage of a list item has corresponding
17119 // storage in the device data environment, all of the original storage
17120 // must have corresponding storage in the device data environment.
17121 //
17122 if (DerivedType->isAnyPointerType()) {
17123 if (CI == CE || SI == SE) {
17124 SemaRef.Diag(
17125 DerivedLoc,
17126 diag::err_omp_pointer_mapped_along_with_derived_section)
17127 << DerivedLoc;
17128 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17129 << RE->getSourceRange();
17130 return true;
17131 }
17132 if (CI->getAssociatedExpression()->getStmtClass() !=
17133 SI->getAssociatedExpression()->getStmtClass() ||
17134 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17135 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17136 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17136, __PRETTY_FUNCTION__))
;
17137 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17138 << DerivedLoc;
17139 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17140 << RE->getSourceRange();
17141 return true;
17142 }
17143 }
17144
17145 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17146 // List items of map clauses in the same construct must not share
17147 // original storage.
17148 //
17149 // An expression is a subset of the other.
17150 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17151 if (CKind == OMPC_map) {
17152 if (CI != CE || SI != SE) {
17153 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17154 // a pointer.
17155 auto Begin =
17156 CI != CE ? CurComponents.begin() : StackComponents.begin();
17157 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17158 auto It = Begin;
17159 while (It != End && !It->getAssociatedDeclaration())
17160 std::advance(It, 1);
17161 assert(It != End &&((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17162, __PRETTY_FUNCTION__))
17162 "Expected at least one component with the declaration.")((It != End && "Expected at least one component with the declaration."
) ? static_cast<void> (0) : __assert_fail ("It != End && \"Expected at least one component with the declaration.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17162, __PRETTY_FUNCTION__))
;
17163 if (It != Begin && It->getAssociatedDeclaration()
17164 ->getType()
17165 .getCanonicalType()
17166 ->isAnyPointerType()) {
17167 IsEnclosedByDataEnvironmentExpr = false;
17168 EnclosingExpr = nullptr;
17169 return false;
17170 }
17171 }
17172 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17173 } else {
17174 assert(CKind == OMPC_to || CKind == OMPC_from)((CKind == OMPC_to || CKind == OMPC_from) ? static_cast<void
> (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17174, __PRETTY_FUNCTION__))
;
17175 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17176 << ERange;
17177 }
17178 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17179 << RE->getSourceRange();
17180 return true;
17181 }
17182
17183 // The current expression uses the same base as other expression in the
17184 // data environment but does not contain it completely.
17185 if (!CurrentRegionOnly && SI != SE)
17186 EnclosingExpr = RE;
17187
17188 // The current expression is a subset of the expression in the data
17189 // environment.
17190 IsEnclosedByDataEnvironmentExpr |=
17191 (!CurrentRegionOnly && CI != CE && SI == SE);
17192
17193 return false;
17194 });
17195
17196 if (CurrentRegionOnly)
17197 return FoundError;
17198
17199 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17200 // If any part of the original storage of a list item has corresponding
17201 // storage in the device data environment, all of the original storage must
17202 // have corresponding storage in the device data environment.
17203 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17204 // If a list item is an element of a structure, and a different element of
17205 // the structure has a corresponding list item in the device data environment
17206 // prior to a task encountering the construct associated with the map clause,
17207 // then the list item must also have a corresponding list item in the device
17208 // data environment prior to the task encountering the construct.
17209 //
17210 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17211 SemaRef.Diag(ELoc,
17212 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17213 << ERange;
17214 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17215 << EnclosingExpr->getSourceRange();
17216 return true;
17217 }
17218
17219 return FoundError;
17220}
17221
17222// Look up the user-defined mapper given the mapper name and mapped type, and
17223// build a reference to it.
17224static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17225 CXXScopeSpec &MapperIdScopeSpec,
17226 const DeclarationNameInfo &MapperId,
17227 QualType Type,
17228 Expr *UnresolvedMapper) {
17229 if (MapperIdScopeSpec.isInvalid())
17230 return ExprError();
17231 // Get the actual type for the array type.
17232 if (Type->isArrayType()) {
17233 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type")((Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"
) ? static_cast<void> (0) : __assert_fail ("Type->getAsArrayTypeUnsafe() && \"Expect to get a valid array type\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17233, __PRETTY_FUNCTION__))
;
17234 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17235 }
17236 // Find all user-defined mappers with the given MapperId.
17237 SmallVector<UnresolvedSet<8>, 4> Lookups;
17238 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17239 Lookup.suppressDiagnostics();
17240 if (S) {
17241 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17242 NamedDecl *D = Lookup.getRepresentativeDecl();
17243 while (S && !S->isDeclScope(D))
17244 S = S->getParent();
17245 if (S)
17246 S = S->getParent();
17247 Lookups.emplace_back();
17248 Lookups.back().append(Lookup.begin(), Lookup.end());
17249 Lookup.clear();
17250 }
17251 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17252 // Extract the user-defined mappers with the given MapperId.
17253 Lookups.push_back(UnresolvedSet<8>());
17254 for (NamedDecl *D : ULE->decls()) {
17255 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17256 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.")((DMD && "Expect valid OMPDeclareMapperDecl during instantiation."
) ? static_cast<void> (0) : __assert_fail ("DMD && \"Expect valid OMPDeclareMapperDecl during instantiation.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17256, __PRETTY_FUNCTION__))
;
17257 Lookups.back().addDecl(DMD);
17258 }
17259 }
17260 // Defer the lookup for dependent types. The results will be passed through
17261 // UnresolvedMapper on instantiation.
17262 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17263 Type->isInstantiationDependentType() ||
17264 Type->containsUnexpandedParameterPack() ||
17265 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17266 return !D->isInvalidDecl() &&
17267 (D->getType()->isDependentType() ||
17268 D->getType()->isInstantiationDependentType() ||
17269 D->getType()->containsUnexpandedParameterPack());
17270 })) {
17271 UnresolvedSet<8> URS;
17272 for (const UnresolvedSet<8> &Set : Lookups) {
17273 if (Set.empty())
17274 continue;
17275 URS.append(Set.begin(), Set.end());
17276 }
17277 return UnresolvedLookupExpr::Create(
17278 SemaRef.Context, /*NamingClass=*/nullptr,
17279 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17280 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17281 }
17282 SourceLocation Loc = MapperId.getLoc();
17283 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17284 // The type must be of struct, union or class type in C and C++
17285 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17286 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17287 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17288 return ExprError();
17289 }
17290 // Perform argument dependent lookup.
17291 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17292 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17293 // Return the first user-defined mapper with the desired type.
17294 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17295 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17296 if (!D->isInvalidDecl() &&
17297 SemaRef.Context.hasSameType(D->getType(), Type))
17298 return D;
17299 return nullptr;
17300 }))
17301 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17302 // Find the first user-defined mapper with a type derived from the desired
17303 // type.
17304 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17305 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17306 if (!D->isInvalidDecl() &&
17307 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17308 !Type.isMoreQualifiedThan(D->getType()))
17309 return D;
17310 return nullptr;
17311 })) {
17312 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17313 /*DetectVirtual=*/false);
17314 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17315 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17316 VD->getType().getUnqualifiedType()))) {
17317 if (SemaRef.CheckBaseClassAccess(
17318 Loc, VD->getType(), Type, Paths.front(),
17319 /*DiagID=*/0) != Sema::AR_inaccessible) {
17320 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17321 }
17322 }
17323 }
17324 }
17325 // Report error if a mapper is specified, but cannot be found.
17326 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17327 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17328 << Type << MapperId.getName();
17329 return ExprError();
17330 }
17331 return ExprEmpty();
17332}
17333
17334namespace {
17335// Utility struct that gathers all the related lists associated with a mappable
17336// expression.
17337struct MappableVarListInfo {
17338 // The list of expressions.
17339 ArrayRef<Expr *> VarList;
17340 // The list of processed expressions.
17341 SmallVector<Expr *, 16> ProcessedVarList;
17342 // The mappble components for each expression.
17343 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17344 // The base declaration of the variable.
17345 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17346 // The reference to the user-defined mapper associated with every expression.
17347 SmallVector<Expr *, 16> UDMapperList;
17348
17349 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17350 // We have a list of components and base declarations for each entry in the
17351 // variable list.
17352 VarComponents.reserve(VarList.size());
17353 VarBaseDeclarations.reserve(VarList.size());
17354 }
17355};
17356}
17357
17358// Check the validity of the provided variable list for the provided clause kind
17359// \a CKind. In the check process the valid expressions, mappable expression
17360// components, variables, and user-defined mappers are extracted and used to
17361// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17362// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17363// and \a MapperId are expected to be valid if the clause kind is 'map'.
17364static void checkMappableExpressionList(
17365 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17366 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17367 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17368 ArrayRef<Expr *> UnresolvedMappers,
17369 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17370 bool IsMapTypeImplicit = false) {
17371 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17372 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17373, __PRETTY_FUNCTION__))
17373 "Unexpected clause kind with mappable expressions!")(((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from
) && "Unexpected clause kind with mappable expressions!"
) ? static_cast<void> (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17373, __PRETTY_FUNCTION__))
;
17374
17375 // If the identifier of user-defined mapper is not specified, it is "default".
17376 // We do not change the actual name in this clause to distinguish whether a
17377 // mapper is specified explicitly, i.e., it is not explicitly specified when
17378 // MapperId.getName() is empty.
17379 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17380 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17381 MapperId.setName(DeclNames.getIdentifier(
17382 &SemaRef.getASTContext().Idents.get("default")));
17383 }
17384
17385 // Iterators to find the current unresolved mapper expression.
17386 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17387 bool UpdateUMIt = false;
17388 Expr *UnresolvedMapper = nullptr;
17389
17390 // Keep track of the mappable components and base declarations in this clause.
17391 // Each entry in the list is going to have a list of components associated. We
17392 // record each set of the components so that we can build the clause later on.
17393 // In the end we should have the same amount of declarations and component
17394 // lists.
17395
17396 for (Expr *RE : MVLI.VarList) {
17397 assert(RE && "Null expr in omp to/from/map clause")((RE && "Null expr in omp to/from/map clause") ? static_cast
<void> (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17397, __PRETTY_FUNCTION__))
;
17398 SourceLocation ELoc = RE->getExprLoc();
17399
17400 // Find the current unresolved mapper expression.
17401 if (UpdateUMIt && UMIt != UMEnd) {
17402 UMIt++;
17403 assert(((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17405, __PRETTY_FUNCTION__))
17404 UMIt != UMEnd &&((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17405, __PRETTY_FUNCTION__))
17405 "Expect the size of UnresolvedMappers to match with that of VarList")((UMIt != UMEnd && "Expect the size of UnresolvedMappers to match with that of VarList"
) ? static_cast<void> (0) : __assert_fail ("UMIt != UMEnd && \"Expect the size of UnresolvedMappers to match with that of VarList\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17405, __PRETTY_FUNCTION__))
;
17406 }
17407 UpdateUMIt = true;
17408 if (UMIt != UMEnd)
17409 UnresolvedMapper = *UMIt;
17410
17411 const Expr *VE = RE->IgnoreParenLValueCasts();
17412
17413 if (VE->isValueDependent() || VE->isTypeDependent() ||
17414 VE->isInstantiationDependent() ||
17415 VE->containsUnexpandedParameterPack()) {
17416 // Try to find the associated user-defined mapper.
17417 ExprResult ER = buildUserDefinedMapperRef(
17418 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17419 VE->getType().getCanonicalType(), UnresolvedMapper);
17420 if (ER.isInvalid())
17421 continue;
17422 MVLI.UDMapperList.push_back(ER.get());
17423 // We can only analyze this information once the missing information is
17424 // resolved.
17425 MVLI.ProcessedVarList.push_back(RE);
17426 continue;
17427 }
17428
17429 Expr *SimpleExpr = RE->IgnoreParenCasts();
17430
17431 if (!RE->isLValue()) {
17432 if (SemaRef.getLangOpts().OpenMP < 50) {
17433 SemaRef.Diag(
17434 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17435 << RE->getSourceRange();
17436 } else {
17437 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17438 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17439 }
17440 continue;
17441 }
17442
17443 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17444 ValueDecl *CurDeclaration = nullptr;
17445
17446 // Obtain the array or member expression bases if required. Also, fill the
17447 // components array with all the components identified in the process.
17448 const Expr *BE = checkMapClauseExpressionBase(
17449 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
17450 if (!BE)
17451 continue;
17452
17453 assert(!CurComponents.empty() &&((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17454, __PRETTY_FUNCTION__))
17454 "Invalid mappable expression information.")((!CurComponents.empty() && "Invalid mappable expression information."
) ? static_cast<void> (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17454, __PRETTY_FUNCTION__))
;
17455
17456 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17457 // Add store "this" pointer to class in DSAStackTy for future checking
17458 DSAS->addMappedClassesQualTypes(TE->getType());
17459 // Try to find the associated user-defined mapper.
17460 ExprResult ER = buildUserDefinedMapperRef(
17461 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17462 VE->getType().getCanonicalType(), UnresolvedMapper);
17463 if (ER.isInvalid())
17464 continue;
17465 MVLI.UDMapperList.push_back(ER.get());
17466 // Skip restriction checking for variable or field declarations
17467 MVLI.ProcessedVarList.push_back(RE);
17468 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17469 MVLI.VarComponents.back().append(CurComponents.begin(),
17470 CurComponents.end());
17471 MVLI.VarBaseDeclarations.push_back(nullptr);
17472 continue;
17473 }
17474
17475 // For the following checks, we rely on the base declaration which is
17476 // expected to be associated with the last component. The declaration is
17477 // expected to be a variable or a field (if 'this' is being mapped).
17478 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17479 assert(CurDeclaration && "Null decl on map clause.")((CurDeclaration && "Null decl on map clause.") ? static_cast
<void> (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17479, __PRETTY_FUNCTION__))
;
17480 assert(((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17482, __PRETTY_FUNCTION__))
17481 CurDeclaration->isCanonicalDecl() &&((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17482, __PRETTY_FUNCTION__))
17482 "Expecting components to have associated only canonical declarations.")((CurDeclaration->isCanonicalDecl() && "Expecting components to have associated only canonical declarations."
) ? static_cast<void> (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17482, __PRETTY_FUNCTION__))
;
17483
17484 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17485 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17486
17487 assert((VD || FD) && "Only variables or fields are expected here!")(((VD || FD) && "Only variables or fields are expected here!"
) ? static_cast<void> (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17487, __PRETTY_FUNCTION__))
;
17488 (void)FD;
17489
17490 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17491 // threadprivate variables cannot appear in a map clause.
17492 // OpenMP 4.5 [2.10.5, target update Construct]
17493 // threadprivate variables cannot appear in a from clause.
17494 if (VD && DSAS->isThreadPrivate(VD)) {
17495 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17496 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17497 << getOpenMPClauseName(CKind);
17498 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17499 continue;
17500 }
17501
17502 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17503 // A list item cannot appear in both a map clause and a data-sharing
17504 // attribute clause on the same construct.
17505
17506 // Check conflicts with other map clause expressions. We check the conflicts
17507 // with the current construct separately from the enclosing data
17508 // environment, because the restrictions are different. We only have to
17509 // check conflicts across regions for the map clauses.
17510 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17511 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17512 break;
17513 if (CKind == OMPC_map &&
17514 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
17515 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17516 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17517 break;
17518
17519 // OpenMP 4.5 [2.10.5, target update Construct]
17520 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17521 // If the type of a list item is a reference to a type T then the type will
17522 // be considered to be T for all purposes of this clause.
17523 auto I = llvm::find_if(
17524 CurComponents,
17525 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17526 return MC.getAssociatedDeclaration();
17527 });
17528 assert(I != CurComponents.end() && "Null decl on map clause.")((I != CurComponents.end() && "Null decl on map clause."
) ? static_cast<void> (0) : __assert_fail ("I != CurComponents.end() && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17528, __PRETTY_FUNCTION__))
;
17529 QualType Type;
17530 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17531 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17532 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17533 if (ASE) {
17534 Type = ASE->getType().getNonReferenceType();
17535 } else if (OASE) {
17536 QualType BaseType =
17537 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17538 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17539 Type = ATy->getElementType();
17540 else
17541 Type = BaseType->getPointeeType();
17542 Type = Type.getNonReferenceType();
17543 } else if (OAShE) {
17544 Type = OAShE->getBase()->getType()->getPointeeType();
17545 } else {
17546 Type = VE->getType();
17547 }
17548
17549 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17550 // A list item in a to or from clause must have a mappable type.
17551 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17552 // A list item must have a mappable type.
17553 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17554 DSAS, Type))
17555 continue;
17556
17557 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17558
17559 if (CKind == OMPC_map) {
17560 // target enter data
17561 // OpenMP [2.10.2, Restrictions, p. 99]
17562 // A map-type must be specified in all map clauses and must be either
17563 // to or alloc.
17564 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17565 if (DKind == OMPD_target_enter_data &&
17566 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17567 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17568 << (IsMapTypeImplicit ? 1 : 0)
17569 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17570 << getOpenMPDirectiveName(DKind);
17571 continue;
17572 }
17573
17574 // target exit_data
17575 // OpenMP [2.10.3, Restrictions, p. 102]
17576 // A map-type must be specified in all map clauses and must be either
17577 // from, release, or delete.
17578 if (DKind == OMPD_target_exit_data &&
17579 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17580 MapType == OMPC_MAP_delete)) {
17581 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17582 << (IsMapTypeImplicit ? 1 : 0)
17583 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17584 << getOpenMPDirectiveName(DKind);
17585 continue;
17586 }
17587
17588 // target, target data
17589 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17590 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17591 // A map-type in a map clause must be to, from, tofrom or alloc
17592 if ((DKind == OMPD_target_data ||
17593 isOpenMPTargetExecutionDirective(DKind)) &&
17594 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17595 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17596 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17597 << (IsMapTypeImplicit ? 1 : 0)
17598 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17599 << getOpenMPDirectiveName(DKind);
17600 continue;
17601 }
17602
17603 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17604 // A list item cannot appear in both a map clause and a data-sharing
17605 // attribute clause on the same construct
17606 //
17607 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17608 // A list item cannot appear in both a map clause and a data-sharing
17609 // attribute clause on the same construct unless the construct is a
17610 // combined construct.
17611 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17612 isOpenMPTargetExecutionDirective(DKind)) ||
17613 DKind == OMPD_target)) {
17614 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17615 if (isOpenMPPrivate(DVar.CKind)) {
17616 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17617 << getOpenMPClauseName(DVar.CKind)
17618 << getOpenMPClauseName(OMPC_map)
17619 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17620 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17621 continue;
17622 }
17623 }
17624 }
17625
17626 // Try to find the associated user-defined mapper.
17627 ExprResult ER = buildUserDefinedMapperRef(
17628 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17629 Type.getCanonicalType(), UnresolvedMapper);
17630 if (ER.isInvalid())
17631 continue;
17632 MVLI.UDMapperList.push_back(ER.get());
17633
17634 // Save the current expression.
17635 MVLI.ProcessedVarList.push_back(RE);
17636
17637 // Store the components in the stack so that they can be used to check
17638 // against other clauses later on.
17639 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17640 /*WhereFoundClauseKind=*/OMPC_map);
17641
17642 // Save the components and declaration to create the clause. For purposes of
17643 // the clause creation, any component list that has has base 'this' uses
17644 // null as base declaration.
17645 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17646 MVLI.VarComponents.back().append(CurComponents.begin(),
17647 CurComponents.end());
17648 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17649 : CurDeclaration);
17650 }
17651}
17652
17653OMPClause *Sema::ActOnOpenMPMapClause(
17654 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17655 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17656 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17657 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17658 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17659 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17660 OpenMPMapModifierKind Modifiers[] = {
17661 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
17662 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
17663 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17664
17665 // Process map-type-modifiers, flag errors for duplicate modifiers.
17666 unsigned Count = 0;
17667 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17668 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17669 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17670 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17671 continue;
17672 }
17673 assert(Count < NumberOfOMPMapClauseModifiers &&((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17674, __PRETTY_FUNCTION__))
17674 "Modifiers exceed the allowed number of map type modifiers")((Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMapClauseModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17674, __PRETTY_FUNCTION__))
;
17675 Modifiers[Count] = MapTypeModifiers[I];
17676 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17677 ++Count;
17678 }
17679
17680 MappableVarListInfo MVLI(VarList);
17681 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
17682 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17683 MapType, IsMapTypeImplicit);
17684
17685 // We need to produce a map clause even if we don't have variables so that
17686 // other diagnostics related with non-existing map clauses are accurate.
17687 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17688 MVLI.VarBaseDeclarations, MVLI.VarComponents,
17689 MVLI.UDMapperList, Modifiers, ModifiersLoc,
17690 MapperIdScopeSpec.getWithLocInContext(Context),
17691 MapperId, MapType, IsMapTypeImplicit, MapLoc);
17692}
17693
17694QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17695 TypeResult ParsedType) {
17696 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17696, __PRETTY_FUNCTION__))
;
17697
17698 QualType ReductionType = GetTypeFromParser(ParsedType.get());
17699 if (ReductionType.isNull())
17700 return QualType();
17701
17702 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17703 // A type name in a declare reduction directive cannot be a function type, an
17704 // array type, a reference type, or a type qualified with const, volatile or
17705 // restrict.
17706 if (ReductionType.hasQualifiers()) {
17707 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17708 return QualType();
17709 }
17710
17711 if (ReductionType->isFunctionType()) {
17712 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17713 return QualType();
17714 }
17715 if (ReductionType->isReferenceType()) {
17716 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17717 return QualType();
17718 }
17719 if (ReductionType->isArrayType()) {
17720 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17721 return QualType();
17722 }
17723 return ReductionType;
17724}
17725
17726Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17727 Scope *S, DeclContext *DC, DeclarationName Name,
17728 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17729 AccessSpecifier AS, Decl *PrevDeclInScope) {
17730 SmallVector<Decl *, 8> Decls;
17731 Decls.reserve(ReductionTypes.size());
17732
17733 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17734 forRedeclarationInCurContext());
17735 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17736 // A reduction-identifier may not be re-declared in the current scope for the
17737 // same type or for a type that is compatible according to the base language
17738 // rules.
17739 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17740 OMPDeclareReductionDecl *PrevDRD = nullptr;
17741 bool InCompoundScope = true;
17742 if (S != nullptr) {
17743 // Find previous declaration with the same name not referenced in other
17744 // declarations.
17745 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17746 InCompoundScope =
17747 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17748 LookupName(Lookup, S);
17749 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17750 /*AllowInlineNamespace=*/false);
17751 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17752 LookupResult::Filter Filter = Lookup.makeFilter();
17753 while (Filter.hasNext()) {
17754 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17755 if (InCompoundScope) {
17756 auto I = UsedAsPrevious.find(PrevDecl);
17757 if (I == UsedAsPrevious.end())
17758 UsedAsPrevious[PrevDecl] = false;
17759 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17760 UsedAsPrevious[D] = true;
17761 }
17762 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17763 PrevDecl->getLocation();
17764 }
17765 Filter.done();
17766 if (InCompoundScope) {
17767 for (const auto &PrevData : UsedAsPrevious) {
17768 if (!PrevData.second) {
17769 PrevDRD = PrevData.first;
17770 break;
17771 }
17772 }
17773 }
17774 } else if (PrevDeclInScope != nullptr) {
17775 auto *PrevDRDInScope = PrevDRD =
17776 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17777 do {
17778 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17779 PrevDRDInScope->getLocation();
17780 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17781 } while (PrevDRDInScope != nullptr);
17782 }
17783 for (const auto &TyData : ReductionTypes) {
17784 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17785 bool Invalid = false;
17786 if (I != PreviousRedeclTypes.end()) {
17787 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17788 << TyData.first;
17789 Diag(I->second, diag::note_previous_definition);
17790 Invalid = true;
17791 }
17792 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17793 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17794 Name, TyData.first, PrevDRD);
17795 DC->addDecl(DRD);
17796 DRD->setAccess(AS);
17797 Decls.push_back(DRD);
17798 if (Invalid)
17799 DRD->setInvalidDecl();
17800 else
17801 PrevDRD = DRD;
17802 }
17803
17804 return DeclGroupPtrTy::make(
17805 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17806}
17807
17808void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17809 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17810
17811 // Enter new function scope.
17812 PushFunctionScope();
17813 setFunctionHasBranchProtectedScope();
17814 getCurFunction()->setHasOMPDeclareReductionCombiner();
17815
17816 if (S != nullptr)
17817 PushDeclContext(S, DRD);
17818 else
17819 CurContext = DRD;
17820
17821 PushExpressionEvaluationContext(
17822 ExpressionEvaluationContext::PotentiallyEvaluated);
17823
17824 QualType ReductionType = DRD->getType();
17825 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
17826 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
17827 // uses semantics of argument handles by value, but it should be passed by
17828 // reference. C lang does not support references, so pass all parameters as
17829 // pointers.
17830 // Create 'T omp_in;' variable.
17831 VarDecl *OmpInParm =
17832 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
17833 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
17834 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
17835 // uses semantics of argument handles by value, but it should be passed by
17836 // reference. C lang does not support references, so pass all parameters as
17837 // pointers.
17838 // Create 'T omp_out;' variable.
17839 VarDecl *OmpOutParm =
17840 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
17841 if (S != nullptr) {
17842 PushOnScopeChains(OmpInParm, S);
17843 PushOnScopeChains(OmpOutParm, S);
17844 } else {
17845 DRD->addDecl(OmpInParm);
17846 DRD->addDecl(OmpOutParm);
17847 }
17848 Expr *InE =
17849 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
17850 Expr *OutE =
17851 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
17852 DRD->setCombinerData(InE, OutE);
17853}
17854
17855void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
17856 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17857 DiscardCleanupsInEvaluationContext();
17858 PopExpressionEvaluationContext();
17859
17860 PopDeclContext();
17861 PopFunctionScopeInfo();
17862
17863 if (Combiner != nullptr)
17864 DRD->setCombiner(Combiner);
17865 else
17866 DRD->setInvalidDecl();
17867}
17868
17869VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
17870 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17871
17872 // Enter new function scope.
17873 PushFunctionScope();
17874 setFunctionHasBranchProtectedScope();
17875
17876 if (S != nullptr)
17877 PushDeclContext(S, DRD);
17878 else
17879 CurContext = DRD;
17880
17881 PushExpressionEvaluationContext(
17882 ExpressionEvaluationContext::PotentiallyEvaluated);
17883
17884 QualType ReductionType = DRD->getType();
17885 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
17886 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
17887 // uses semantics of argument handles by value, but it should be passed by
17888 // reference. C lang does not support references, so pass all parameters as
17889 // pointers.
17890 // Create 'T omp_priv;' variable.
17891 VarDecl *OmpPrivParm =
17892 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
17893 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
17894 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
17895 // uses semantics of argument handles by value, but it should be passed by
17896 // reference. C lang does not support references, so pass all parameters as
17897 // pointers.
17898 // Create 'T omp_orig;' variable.
17899 VarDecl *OmpOrigParm =
17900 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
17901 if (S != nullptr) {
17902 PushOnScopeChains(OmpPrivParm, S);
17903 PushOnScopeChains(OmpOrigParm, S);
17904 } else {
17905 DRD->addDecl(OmpPrivParm);
17906 DRD->addDecl(OmpOrigParm);
17907 }
17908 Expr *OrigE =
17909 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
17910 Expr *PrivE =
17911 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
17912 DRD->setInitializerData(OrigE, PrivE);
17913 return OmpPrivParm;
17914}
17915
17916void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
17917 VarDecl *OmpPrivParm) {
17918 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17919 DiscardCleanupsInEvaluationContext();
17920 PopExpressionEvaluationContext();
17921
17922 PopDeclContext();
17923 PopFunctionScopeInfo();
17924
17925 if (Initializer != nullptr) {
17926 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
17927 } else if (OmpPrivParm->hasInit()) {
17928 DRD->setInitializer(OmpPrivParm->getInit(),
17929 OmpPrivParm->isDirectInit()
17930 ? OMPDeclareReductionDecl::DirectInit
17931 : OMPDeclareReductionDecl::CopyInit);
17932 } else {
17933 DRD->setInvalidDecl();
17934 }
17935}
17936
17937Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
17938 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
17939 for (Decl *D : DeclReductions.get()) {
17940 if (IsValid) {
17941 if (S)
17942 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
17943 /*AddToContext=*/false);
17944 } else {
17945 D->setInvalidDecl();
17946 }
17947 }
17948 return DeclReductions;
17949}
17950
17951TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
17952 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
17953 QualType T = TInfo->getType();
17954 if (D.isInvalidType())
17955 return true;
17956
17957 if (getLangOpts().CPlusPlus) {
17958 // Check that there are no default arguments (C++ only).
17959 CheckExtraCXXDefaultArguments(D);
17960 }
17961
17962 return CreateParsedType(T, TInfo);
17963}
17964
17965QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
17966 TypeResult ParsedType) {
17967 assert(ParsedType.isUsable() && "Expect usable parsed mapper type")((ParsedType.isUsable() && "Expect usable parsed mapper type"
) ? static_cast<void> (0) : __assert_fail ("ParsedType.isUsable() && \"Expect usable parsed mapper type\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17967, __PRETTY_FUNCTION__))
;
17968
17969 QualType MapperType = GetTypeFromParser(ParsedType.get());
17970 assert(!MapperType.isNull() && "Expect valid mapper type")((!MapperType.isNull() && "Expect valid mapper type")
? static_cast<void> (0) : __assert_fail ("!MapperType.isNull() && \"Expect valid mapper type\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 17970, __PRETTY_FUNCTION__))
;
17971
17972 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17973 // The type must be of struct, union or class type in C and C++
17974 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
17975 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
17976 return QualType();
17977 }
17978 return MapperType;
17979}
17980
17981OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
17982 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
17983 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
17984 Decl *PrevDeclInScope) {
17985 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
17986 forRedeclarationInCurContext());
17987 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17988 // A mapper-identifier may not be redeclared in the current scope for the
17989 // same type or for a type that is compatible according to the base language
17990 // rules.
17991 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17992 OMPDeclareMapperDecl *PrevDMD = nullptr;
17993 bool InCompoundScope = true;
17994 if (S != nullptr) {
17995 // Find previous declaration with the same name not referenced in other
17996 // declarations.
17997 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17998 InCompoundScope =
17999 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
18000 LookupName(Lookup, S);
18001 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
18002 /*AllowInlineNamespace=*/false);
18003 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
18004 LookupResult::Filter Filter = Lookup.makeFilter();
18005 while (Filter.hasNext()) {
18006 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
18007 if (InCompoundScope) {
18008 auto I = UsedAsPrevious.find(PrevDecl);
18009 if (I == UsedAsPrevious.end())
18010 UsedAsPrevious[PrevDecl] = false;
18011 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
18012 UsedAsPrevious[D] = true;
18013 }
18014 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
18015 PrevDecl->getLocation();
18016 }
18017 Filter.done();
18018 if (InCompoundScope) {
18019 for (const auto &PrevData : UsedAsPrevious) {
18020 if (!PrevData.second) {
18021 PrevDMD = PrevData.first;
18022 break;
18023 }
18024 }
18025 }
18026 } else if (PrevDeclInScope) {
18027 auto *PrevDMDInScope = PrevDMD =
18028 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18029 do {
18030 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18031 PrevDMDInScope->getLocation();
18032 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18033 } while (PrevDMDInScope != nullptr);
18034 }
18035 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18036 bool Invalid = false;
18037 if (I != PreviousRedeclTypes.end()) {
18038 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18039 << MapperType << Name;
18040 Diag(I->second, diag::note_previous_definition);
18041 Invalid = true;
18042 }
18043 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18044 MapperType, VN, PrevDMD);
18045 DC->addDecl(DMD);
18046 DMD->setAccess(AS);
18047 if (Invalid)
18048 DMD->setInvalidDecl();
18049
18050 // Enter new function scope.
18051 PushFunctionScope();
18052 setFunctionHasBranchProtectedScope();
18053
18054 CurContext = DMD;
18055
18056 return DMD;
18057}
18058
18059void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
18060 Scope *S,
18061 QualType MapperType,
18062 SourceLocation StartLoc,
18063 DeclarationName VN) {
18064 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
18065 if (S)
18066 PushOnScopeChains(VD, S);
18067 else
18068 DMD->addDecl(VD);
18069 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18070 DMD->setMapperVarRef(MapperVarRefExpr);
18071}
18072
18073Sema::DeclGroupPtrTy
18074Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
18075 ArrayRef<OMPClause *> ClauseList) {
18076 PopDeclContext();
18077 PopFunctionScopeInfo();
18078
18079 if (D) {
18080 if (S)
18081 PushOnScopeChains(D, S, /*AddToContext=*/false);
18082 D->CreateClauses(Context, ClauseList);
18083 }
18084
18085 return DeclGroupPtrTy::make(DeclGroupRef(D));
18086}
18087
18088OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18089 SourceLocation StartLoc,
18090 SourceLocation LParenLoc,
18091 SourceLocation EndLoc) {
18092 Expr *ValExpr = NumTeams;
18093 Stmt *HelperValStmt = nullptr;
18094
18095 // OpenMP [teams Constrcut, Restrictions]
18096 // The num_teams expression must evaluate to a positive integer value.
18097 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18098 /*StrictlyPositive=*/true))
18099 return nullptr;
18100
18101 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18102 OpenMPDirectiveKind CaptureRegion =
18103 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18104 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18105 ValExpr = MakeFullExpr(ValExpr).get();
18106 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18107 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18108 HelperValStmt = buildPreInits(Context, Captures);
18109 }
18110
18111 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18112 StartLoc, LParenLoc, EndLoc);
18113}
18114
18115OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18116 SourceLocation StartLoc,
18117 SourceLocation LParenLoc,
18118 SourceLocation EndLoc) {
18119 Expr *ValExpr = ThreadLimit;
18120 Stmt *HelperValStmt = nullptr;
18121
18122 // OpenMP [teams Constrcut, Restrictions]
18123 // The thread_limit expression must evaluate to a positive integer value.
18124 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18125 /*StrictlyPositive=*/true))
18126 return nullptr;
18127
18128 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
18129 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18130 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18131 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18132 ValExpr = MakeFullExpr(ValExpr).get();
18133 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18134 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18135 HelperValStmt = buildPreInits(Context, Captures);
18136 }
18137
18138 return new (Context) OMPThreadLimitClause(
18139 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18140}
18141
18142OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18143 SourceLocation StartLoc,
18144 SourceLocation LParenLoc,
18145 SourceLocation EndLoc) {
18146 Expr *ValExpr = Priority;
18147 Stmt *HelperValStmt = nullptr;
18148 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18149
18150 // OpenMP [2.9.1, task Constrcut]
18151 // The priority-value is a non-negative numerical scalar expression.
18152 if (!isNonNegativeIntegerValue(
18153 ValExpr, *this, OMPC_priority,
18154 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18155 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18156 return nullptr;
18157
18158 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18159 StartLoc, LParenLoc, EndLoc);
18160}
18161
18162OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18163 SourceLocation StartLoc,
18164 SourceLocation LParenLoc,
18165 SourceLocation EndLoc) {
18166 Expr *ValExpr = Grainsize;
18167 Stmt *HelperValStmt = nullptr;
18168 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18169
18170 // OpenMP [2.9.2, taskloop Constrcut]
18171 // The parameter of the grainsize clause must be a positive integer
18172 // expression.
18173 if (!isNonNegativeIntegerValue(
18174 ValExpr, *this, OMPC_grainsize,
18175 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18176 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18177 return nullptr;
18178
18179 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18180 StartLoc, LParenLoc, EndLoc);
18181}
18182
18183OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18184 SourceLocation StartLoc,
18185 SourceLocation LParenLoc,
18186 SourceLocation EndLoc) {
18187 Expr *ValExpr = NumTasks;
18188 Stmt *HelperValStmt = nullptr;
18189 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18190
18191 // OpenMP [2.9.2, taskloop Constrcut]
18192 // The parameter of the num_tasks clause must be a positive integer
18193 // expression.
18194 if (!isNonNegativeIntegerValue(
18195 ValExpr, *this, OMPC_num_tasks,
18196 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18197 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18198 return nullptr;
18199
18200 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18201 StartLoc, LParenLoc, EndLoc);
18202}
18203
18204OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18205 SourceLocation LParenLoc,
18206 SourceLocation EndLoc) {
18207 // OpenMP [2.13.2, critical construct, Description]
18208 // ... where hint-expression is an integer constant expression that evaluates
18209 // to a valid lock hint.
18210 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18211 if (HintExpr.isInvalid())
18212 return nullptr;
18213 return new (Context)
18214 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18215}
18216
18217/// Tries to find omp_event_handle_t type.
18218static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18219 DSAStackTy *Stack) {
18220 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18221 if (!OMPEventHandleT.isNull())
18222 return true;
18223 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18224 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18225 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18226 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18227 return false;
18228 }
18229 Stack->setOMPEventHandleT(PT.get());
18230 return true;
18231}
18232
18233OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18234 SourceLocation LParenLoc,
18235 SourceLocation EndLoc) {
18236 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18237 !Evt->isInstantiationDependent() &&
18238 !Evt->containsUnexpandedParameterPack()) {
18239 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
18240 return nullptr;
18241 // OpenMP 5.0, 2.10.1 task Construct.
18242 // event-handle is a variable of the omp_event_handle_t type.
18243 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18244 if (!Ref) {
18245 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18246 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18247 return nullptr;
18248 }
18249 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18250 if (!VD) {
18251 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18252 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18253 return nullptr;
18254 }
18255 if (!Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPEventHandleT(),
18256 VD->getType()) ||
18257 VD->getType().isConstant(Context)) {
18258 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18259 << "omp_event_handle_t" << 1 << VD->getType()
18260 << Evt->getSourceRange();
18261 return nullptr;
18262 }
18263 // OpenMP 5.0, 2.10.1 task Construct
18264 // [detach clause]... The event-handle will be considered as if it was
18265 // specified on a firstprivate clause.
18266 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
18267 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18268 DVar.RefExpr) {
18269 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18270 << getOpenMPClauseName(DVar.CKind)
18271 << getOpenMPClauseName(OMPC_firstprivate);
18272 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DVar);
18273 return nullptr;
18274 }
18275 }
18276
18277 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18278}
18279
18280OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18281 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18282 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18283 SourceLocation EndLoc) {
18284 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18285 std::string Values;
18286 Values += "'";
18287 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18288 Values += "'";
18289 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18290 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18291 return nullptr;
18292 }
18293 Expr *ValExpr = ChunkSize;
18294 Stmt *HelperValStmt = nullptr;
18295 if (ChunkSize) {
18296 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18297 !ChunkSize->isInstantiationDependent() &&
18298 !ChunkSize->containsUnexpandedParameterPack()) {
18299 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18300 ExprResult Val =
18301 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18302 if (Val.isInvalid())
18303 return nullptr;
18304
18305 ValExpr = Val.get();
18306
18307 // OpenMP [2.7.1, Restrictions]
18308 // chunk_size must be a loop invariant integer expression with a positive
18309 // value.
18310 if (Optional<llvm::APSInt> Result =
18311 ValExpr->getIntegerConstantExpr(Context)) {
18312 if (Result->isSigned() && !Result->isStrictlyPositive()) {
18313 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18314 << "dist_schedule" << ChunkSize->getSourceRange();
18315 return nullptr;
18316 }
18317 } else if (getOpenMPCaptureRegionForClause(
18318 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
18319 LangOpts.OpenMP) != OMPD_unknown &&
18320 !CurContext->isDependentContext()) {
18321 ValExpr = MakeFullExpr(ValExpr).get();
18322 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18323 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18324 HelperValStmt = buildPreInits(Context, Captures);
18325 }
18326 }
18327 }
18328
18329 return new (Context)
18330 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18331 Kind, ValExpr, HelperValStmt);
18332}
18333
18334OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18335 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18336 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18337 SourceLocation KindLoc, SourceLocation EndLoc) {
18338 if (getLangOpts().OpenMP < 50) {
18339 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18340 Kind != OMPC_DEFAULTMAP_scalar) {
18341 std::string Value;
18342 SourceLocation Loc;
18343 Value += "'";
18344 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18345 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18346 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18347 Loc = MLoc;
18348 } else {
18349 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18350 OMPC_DEFAULTMAP_scalar);
18351 Loc = KindLoc;
18352 }
18353 Value += "'";
18354 Diag(Loc, diag::err_omp_unexpected_clause_value)
18355 << Value << getOpenMPClauseName(OMPC_defaultmap);
18356 return nullptr;
18357 }
18358 } else {
18359 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18360 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18361 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18362 if (!isDefaultmapKind || !isDefaultmapModifier) {
18363 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18364 "'firstprivate', 'none', 'default'";
18365 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18366 if (!isDefaultmapKind && isDefaultmapModifier) {
18367 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18368 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18369 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18370 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18371 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18372 } else {
18373 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18374 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18375 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18376 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18377 }
18378 return nullptr;
18379 }
18380
18381 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18382 // At most one defaultmap clause for each category can appear on the
18383 // directive.
18384 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
18385 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18386 return nullptr;
18387 }
18388 }
18389 if (Kind == OMPC_DEFAULTMAP_unknown) {
18390 // Variable category is not specified - mark all categories.
18391 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18392 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18393 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18394 } else {
18395 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
18396 }
18397
18398 return new (Context)
18399 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18400}
18401
18402bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18403 DeclContext *CurLexicalContext = getCurLexicalContext();
18404 if (!CurLexicalContext->isFileContext() &&
18405 !CurLexicalContext->isExternCContext() &&
18406 !CurLexicalContext->isExternCXXContext() &&
18407 !isa<CXXRecordDecl>(CurLexicalContext) &&
18408 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18409 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18410 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18411 Diag(Loc, diag::err_omp_region_not_file_context);
18412 return false;
18413 }
18414 ++DeclareTargetNestingLevel;
18415 return true;
18416}
18417
18418void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18419 assert(DeclareTargetNestingLevel > 0 &&((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18420, __PRETTY_FUNCTION__))
18420 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18420, __PRETTY_FUNCTION__))
;
18421 --DeclareTargetNestingLevel;
18422}
18423
18424NamedDecl *
18425Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18426 const DeclarationNameInfo &Id,
18427 NamedDeclSetType &SameDirectiveDecls) {
18428 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18429 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18430
18431 if (Lookup.isAmbiguous())
18432 return nullptr;
18433 Lookup.suppressDiagnostics();
18434
18435 if (!Lookup.isSingleResult()) {
18436 VarOrFuncDeclFilterCCC CCC(*this);
18437 if (TypoCorrection Corrected =
18438 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18439 CTK_ErrorRecovery)) {
18440 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18441 << Id.getName());
18442 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18443 return nullptr;
18444 }
18445
18446 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18447 return nullptr;
18448 }
18449
18450 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18451 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18452 !isa<FunctionTemplateDecl>(ND)) {
18453 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18454 return nullptr;
18455 }
18456 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18457 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18458 return ND;
18459}
18460
18461void Sema::ActOnOpenMPDeclareTargetName(
18462 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18463 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18464 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18466, __PRETTY_FUNCTION__))
18465 isa<FunctionTemplateDecl>(ND)) &&(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18466, __PRETTY_FUNCTION__))
18466 "Expected variable, function or function template.")(((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa
<FunctionTemplateDecl>(ND)) && "Expected variable, function or function template."
) ? static_cast<void> (0) : __assert_fail ("(isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND)) && \"Expected variable, function or function template.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18466, __PRETTY_FUNCTION__))
;
18467
18468 // Diagnose marking after use as it may lead to incorrect diagnosis and
18469 // codegen.
18470 if (LangOpts.OpenMP >= 50 &&
18471 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18472 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18473
18474 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18475 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
18476 if (DevTy.hasValue() && *DevTy != DT) {
18477 Diag(Loc, diag::err_omp_device_type_mismatch)
18478 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18479 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18480 return;
18481 }
18482 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18483 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
18484 if (!Res) {
18485 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
18486 SourceRange(Loc, Loc));
18487 ND->addAttr(A);
18488 if (ASTMutationListener *ML = Context.getASTMutationListener())
18489 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18490 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18491 } else if (*Res != MT) {
18492 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18493 }
18494}
18495
18496static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18497 Sema &SemaRef, Decl *D) {
18498 if (!D || !isa<VarDecl>(D))
18499 return;
18500 auto *VD = cast<VarDecl>(D);
18501 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18502 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18503 if (SemaRef.LangOpts.OpenMP >= 50 &&
18504 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18505 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18506 VD->hasGlobalStorage()) {
18507 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18508 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18509 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18510 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18511 // If a lambda declaration and definition appears between a
18512 // declare target directive and the matching end declare target
18513 // directive, all variables that are captured by the lambda
18514 // expression must also appear in a to clause.
18515 SemaRef.Diag(VD->getLocation(),
18516 diag::err_omp_lambda_capture_in_declare_target_not_to);
18517 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18518 << VD << 0 << SR;
18519 return;
18520 }
18521 }
18522 if (MapTy.hasValue())
18523 return;
18524 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18525 SemaRef.Diag(SL, diag::note_used_here) << SR;
18526}
18527
18528static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18529 Sema &SemaRef, DSAStackTy *Stack,
18530 ValueDecl *VD) {
18531 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18532 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18533 /*FullCheck=*/false);
18534}
18535
18536void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18537 SourceLocation IdLoc) {
18538 if (!D || D->isInvalidDecl())
18539 return;
18540 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18541 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18542 if (auto *VD = dyn_cast<VarDecl>(D)) {
18543 // Only global variables can be marked as declare target.
18544 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18545 !VD->isStaticDataMember())
18546 return;
18547 // 2.10.6: threadprivate variable cannot appear in a declare target
18548 // directive.
18549 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
18550 Diag(SL, diag::err_omp_threadprivate_in_target);
18551 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
18552 return;
18553 }
18554 }
18555 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18556 D = FTD->getTemplatedDecl();
18557 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18558 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18559 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18560 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18561 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18562 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18563 return;
18564 }
18565 }
18566 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18567 // Problem if any with var declared with incomplete type will be reported
18568 // as normal, so no need to check it here.
18569 if ((E || !VD->getType()->isIncompleteType()) &&
18570 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
18571 return;
18572 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18573 // Checking declaration inside declare target region.
18574 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18575 isa<FunctionTemplateDecl>(D)) {
18576 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18577 Context, OMPDeclareTargetDeclAttr::MT_To,
18578 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
18579 D->addAttr(A);
18580 if (ASTMutationListener *ML = Context.getASTMutationListener())
18581 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18582 }
18583 return;
18584 }
18585 }
18586 if (!E)
18587 return;
18588 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18589}
18590
18591OMPClause *Sema::ActOnOpenMPToClause(
18592 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18593 ArrayRef<SourceLocation> MotionModifiersLoc,
18594 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18595 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18596 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18597 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18598 OMPC_MOTION_MODIFIER_unknown};
18599 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18600
18601 // Process motion-modifiers, flag errors for duplicate modifiers.
18602 unsigned Count = 0;
18603 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18604 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18605 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18606 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18607 continue;
18608 }
18609 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18610, __PRETTY_FUNCTION__))
18610 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18610, __PRETTY_FUNCTION__))
;
18611 Modifiers[Count] = MotionModifiers[I];
18612 ModifiersLoc[Count] = MotionModifiersLoc[I];
18613 ++Count;
18614 }
18615
18616 MappableVarListInfo MVLI(VarList);
18617 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
18618 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18619 if (MVLI.ProcessedVarList.empty())
18620 return nullptr;
18621
18622 return OMPToClause::Create(
18623 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18624 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18625 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18626}
18627
18628OMPClause *Sema::ActOnOpenMPFromClause(
18629 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
18630 ArrayRef<SourceLocation> MotionModifiersLoc,
18631 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
18632 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
18633 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
18634 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
18635 OMPC_MOTION_MODIFIER_unknown};
18636 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
18637
18638 // Process motion-modifiers, flag errors for duplicate modifiers.
18639 unsigned Count = 0;
18640 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
18641 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
18642 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
18643 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
18644 continue;
18645 }
18646 assert(Count < NumberOfOMPMotionModifiers &&((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18647, __PRETTY_FUNCTION__))
18647 "Modifiers exceed the allowed number of motion modifiers")((Count < NumberOfOMPMotionModifiers && "Modifiers exceed the allowed number of motion modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < NumberOfOMPMotionModifiers && \"Modifiers exceed the allowed number of motion modifiers\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18647, __PRETTY_FUNCTION__))
;
18648 Modifiers[Count] = MotionModifiers[I];
18649 ModifiersLoc[Count] = MotionModifiersLoc[I];
18650 ++Count;
18651 }
18652
18653 MappableVarListInfo MVLI(VarList);
18654 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
18655 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18656 if (MVLI.ProcessedVarList.empty())
18657 return nullptr;
18658
18659 return OMPFromClause::Create(
18660 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18661 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
18662 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18663}
18664
18665OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18666 const OMPVarListLocTy &Locs) {
18667 MappableVarListInfo MVLI(VarList);
18668 SmallVector<Expr *, 8> PrivateCopies;
18669 SmallVector<Expr *, 8> Inits;
18670
18671 for (Expr *RefExpr : VarList) {
18672 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")((RefExpr && "NULL expr in OpenMP use_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18672, __PRETTY_FUNCTION__))
;
18673 SourceLocation ELoc;
18674 SourceRange ERange;
18675 Expr *SimpleRefExpr = RefExpr;
18676 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18677 if (Res.second) {
18678 // It will be analyzed later.
18679 MVLI.ProcessedVarList.push_back(RefExpr);
18680 PrivateCopies.push_back(nullptr);
18681 Inits.push_back(nullptr);
18682 }
18683 ValueDecl *D = Res.first;
18684 if (!D)
18685 continue;
18686
18687 QualType Type = D->getType();
18688 Type = Type.getNonReferenceType().getUnqualifiedType();
18689
18690 auto *VD = dyn_cast<VarDecl>(D);
18691
18692 // Item should be a pointer or reference to pointer.
18693 if (!Type->isPointerType()) {
18694 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18695 << 0 << RefExpr->getSourceRange();
18696 continue;
18697 }
18698
18699 // Build the private variable and the expression that refers to it.
18700 auto VDPrivate =
18701 buildVarDecl(*this, ELoc, Type, D->getName(),
18702 D->hasAttrs() ? &D->getAttrs() : nullptr,
18703 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18704 if (VDPrivate->isInvalidDecl())
18705 continue;
18706
18707 CurContext->addDecl(VDPrivate);
18708 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18709 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18710
18711 // Add temporary variable to initialize the private copy of the pointer.
18712 VarDecl *VDInit =
18713 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18714 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18715 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18716 AddInitializerToDecl(VDPrivate,
18717 DefaultLvalueConversion(VDInitRefExpr).get(),
18718 /*DirectInit=*/false);
18719
18720 // If required, build a capture to implement the privatization initialized
18721 // with the current list item value.
18722 DeclRefExpr *Ref = nullptr;
18723 if (!VD)
18724 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18725 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18726 PrivateCopies.push_back(VDPrivateRefExpr);
18727 Inits.push_back(VDInitRefExpr);
18728
18729 // We need to add a data sharing attribute for this variable to make sure it
18730 // is correctly captured. A variable that shows up in a use_device_ptr has
18731 // similar properties of a first private variable.
18732 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18733
18734 // Create a mappable component for the list item. List items in this clause
18735 // only need a component.
18736 MVLI.VarBaseDeclarations.push_back(D);
18737 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18738 MVLI.VarComponents.back().push_back(
18739 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
18740 }
18741
18742 if (MVLI.ProcessedVarList.empty())
18743 return nullptr;
18744
18745 return OMPUseDevicePtrClause::Create(
18746 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18747 MVLI.VarBaseDeclarations, MVLI.VarComponents);
18748}
18749
18750OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18751 const OMPVarListLocTy &Locs) {
18752 MappableVarListInfo MVLI(VarList);
18753
18754 for (Expr *RefExpr : VarList) {
18755 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.")((RefExpr && "NULL expr in OpenMP use_device_addr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_addr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18755, __PRETTY_FUNCTION__))
;
18756 SourceLocation ELoc;
18757 SourceRange ERange;
18758 Expr *SimpleRefExpr = RefExpr;
18759 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18760 /*AllowArraySection=*/true);
18761 if (Res.second) {
18762 // It will be analyzed later.
18763 MVLI.ProcessedVarList.push_back(RefExpr);
18764 }
18765 ValueDecl *D = Res.first;
18766 if (!D)
18767 continue;
18768 auto *VD = dyn_cast<VarDecl>(D);
18769
18770 // If required, build a capture to implement the privatization initialized
18771 // with the current list item value.
18772 DeclRefExpr *Ref = nullptr;
18773 if (!VD)
18774 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18775 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18776
18777 // We need to add a data sharing attribute for this variable to make sure it
18778 // is correctly captured. A variable that shows up in a use_device_addr has
18779 // similar properties of a first private variable.
18780 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18781
18782 // Create a mappable component for the list item. List items in this clause
18783 // only need a component.
18784 MVLI.VarBaseDeclarations.push_back(D);
18785 MVLI.VarComponents.emplace_back();
18786 Expr *Component = SimpleRefExpr;
18787 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18788 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18789 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18790 MVLI.VarComponents.back().push_back(
18791 OMPClauseMappableExprCommon::MappableComponent(Component, D));
18792 }
18793
18794 if (MVLI.ProcessedVarList.empty())
18795 return nullptr;
18796
18797 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18798 MVLI.VarBaseDeclarations,
18799 MVLI.VarComponents);
18800}
18801
18802OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18803 const OMPVarListLocTy &Locs) {
18804 MappableVarListInfo MVLI(VarList);
18805 for (Expr *RefExpr : VarList) {
18806 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")((RefExpr && "NULL expr in OpenMP is_device_ptr clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18806, __PRETTY_FUNCTION__))
;
18807 SourceLocation ELoc;
18808 SourceRange ERange;
18809 Expr *SimpleRefExpr = RefExpr;
18810 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18811 if (Res.second) {
18812 // It will be analyzed later.
18813 MVLI.ProcessedVarList.push_back(RefExpr);
18814 }
18815 ValueDecl *D = Res.first;
18816 if (!D)
18817 continue;
18818
18819 QualType Type = D->getType();
18820 // item should be a pointer or array or reference to pointer or array
18821 if (!Type.getNonReferenceType()->isPointerType() &&
18822 !Type.getNonReferenceType()->isArrayType()) {
18823 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
18824 << 0 << RefExpr->getSourceRange();
18825 continue;
18826 }
18827
18828 // Check if the declaration in the clause does not show up in any data
18829 // sharing attribute.
18830 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
18831 if (isOpenMPPrivate(DVar.CKind)) {
18832 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18833 << getOpenMPClauseName(DVar.CKind)
18834 << getOpenMPClauseName(OMPC_is_device_ptr)
18835 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
18836 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
18837 continue;
18838 }
18839
18840 const Expr *ConflictExpr;
18841 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
18842 D, /*CurrentRegionOnly=*/true,
18843 [&ConflictExpr](
18844 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
18845 OpenMPClauseKind) -> bool {
18846 ConflictExpr = R.front().getAssociatedExpression();
18847 return true;
18848 })) {
18849 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
18850 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
18851 << ConflictExpr->getSourceRange();
18852 continue;
18853 }
18854
18855 // Store the components in the stack so that they can be used to check
18856 // against other clauses later on.
18857 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
18858 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
18859 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
18860
18861 // Record the expression we've just processed.
18862 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
18863
18864 // Create a mappable component for the list item. List items in this clause
18865 // only need a component. We use a null declaration to signal fields in
18866 // 'this'.
18867 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18869, __PRETTY_FUNCTION__))
18868 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18869, __PRETTY_FUNCTION__))
18869 "Unexpected device pointer expression!")(((isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr
>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
"Unexpected device pointer expression!") ? static_cast<void
> (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18869, __PRETTY_FUNCTION__))
;
18870 MVLI.VarBaseDeclarations.push_back(
18871 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
18872 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18873 MVLI.VarComponents.back().push_back(MC);
18874 }
18875
18876 if (MVLI.ProcessedVarList.empty())
18877 return nullptr;
18878
18879 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18880 MVLI.VarBaseDeclarations,
18881 MVLI.VarComponents);
18882}
18883
18884OMPClause *Sema::ActOnOpenMPAllocateClause(
18885 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18886 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
18887 if (Allocator) {
18888 // OpenMP [2.11.4 allocate Clause, Description]
18889 // allocator is an expression of omp_allocator_handle_t type.
18890 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
18891 return nullptr;
18892
18893 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
18894 if (AllocatorRes.isInvalid())
18895 return nullptr;
18896 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
18897 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
18898 Sema::AA_Initializing,
18899 /*AllowExplicit=*/true);
18900 if (AllocatorRes.isInvalid())
18901 return nullptr;
18902 Allocator = AllocatorRes.get();
18903 } else {
18904 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
18905 // allocate clauses that appear on a target construct or on constructs in a
18906 // target region must specify an allocator expression unless a requires
18907 // directive with the dynamic_allocators clause is present in the same
18908 // compilation unit.
18909 if (LangOpts.OpenMPIsDevice &&
18910 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
18911 targetDiag(StartLoc, diag::err_expected_allocator_expression);
18912 }
18913 // Analyze and build list of variables.
18914 SmallVector<Expr *, 8> Vars;
18915 for (Expr *RefExpr : VarList) {
18916 assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ?
static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18916, __PRETTY_FUNCTION__))
;
18917 SourceLocation ELoc;
18918 SourceRange ERange;
18919 Expr *SimpleRefExpr = RefExpr;
18920 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18921 if (Res.second) {
18922 // It will be analyzed later.
18923 Vars.push_back(RefExpr);
18924 }
18925 ValueDecl *D = Res.first;
18926 if (!D)
18927 continue;
18928
18929 auto *VD = dyn_cast<VarDecl>(D);
18930 DeclRefExpr *Ref = nullptr;
18931 if (!VD && !CurContext->isDependentContext())
18932 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18933 Vars.push_back((VD || CurContext->isDependentContext())
18934 ? RefExpr->IgnoreParens()
18935 : Ref);
18936 }
18937
18938 if (Vars.empty())
18939 return nullptr;
18940
18941 if (Allocator)
18942 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
18943 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
18944 ColonLoc, EndLoc, Vars);
18945}
18946
18947OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
18948 SourceLocation StartLoc,
18949 SourceLocation LParenLoc,
18950 SourceLocation EndLoc) {
18951 SmallVector<Expr *, 8> Vars;
18952 for (Expr *RefExpr : VarList) {
18953 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18953, __PRETTY_FUNCTION__))
;
18954 SourceLocation ELoc;
18955 SourceRange ERange;
18956 Expr *SimpleRefExpr = RefExpr;
18957 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18958 if (Res.second)
18959 // It will be analyzed later.
18960 Vars.push_back(RefExpr);
18961 ValueDecl *D = Res.first;
18962 if (!D)
18963 continue;
18964
18965 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
18966 // A list-item cannot appear in more than one nontemporal clause.
18967 if (const Expr *PrevRef =
18968 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
18969 Diag(ELoc, diag::err_omp_used_in_clause_twice)
18970 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
18971 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
18972 << getOpenMPClauseName(OMPC_nontemporal);
18973 continue;
18974 }
18975
18976 Vars.push_back(RefExpr);
18977 }
18978
18979 if (Vars.empty())
18980 return nullptr;
18981
18982 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18983 Vars);
18984}
18985
18986OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
18987 SourceLocation StartLoc,
18988 SourceLocation LParenLoc,
18989 SourceLocation EndLoc) {
18990 SmallVector<Expr *, 8> Vars;
18991 for (Expr *RefExpr : VarList) {
18992 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 18992, __PRETTY_FUNCTION__))
;
18993 SourceLocation ELoc;
18994 SourceRange ERange;
18995 Expr *SimpleRefExpr = RefExpr;
18996 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18997 /*AllowArraySection=*/true);
18998 if (Res.second)
18999 // It will be analyzed later.
19000 Vars.push_back(RefExpr);
19001 ValueDecl *D = Res.first;
19002 if (!D)
19003 continue;
19004
19005 const DSAStackTy::DSAVarData DVar =
19006 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19007 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19008 // A list item that appears in the inclusive or exclusive clause must appear
19009 // in a reduction clause with the inscan modifier on the enclosing
19010 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19011 if (DVar.CKind != OMPC_reduction ||
19012 DVar.Modifier != OMPC_REDUCTION_inscan)
19013 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19014 << RefExpr->getSourceRange();
19015
19016 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)
19017 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19018 Vars.push_back(RefExpr);
19019 }
19020
19021 if (Vars.empty())
19022 return nullptr;
19023
19024 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19025}
19026
19027OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
19028 SourceLocation StartLoc,
19029 SourceLocation LParenLoc,
19030 SourceLocation EndLoc) {
19031 SmallVector<Expr *, 8> Vars;
19032 for (Expr *RefExpr : VarList) {
19033 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.")((RefExpr && "NULL expr in OpenMP nontemporal clause."
) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP nontemporal clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 19033, __PRETTY_FUNCTION__))
;
19034 SourceLocation ELoc;
19035 SourceRange ERange;
19036 Expr *SimpleRefExpr = RefExpr;
19037 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
19038 /*AllowArraySection=*/true);
19039 if (Res.second)
19040 // It will be analyzed later.
19041 Vars.push_back(RefExpr);
19042 ValueDecl *D = Res.first;
19043 if (!D)
19044 continue;
19045
19046 OpenMPDirectiveKind ParentDirective = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective();
19047 DSAStackTy::DSAVarData DVar;
19048 if (ParentDirective != OMPD_unknown)
19049 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/true);
19050 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
19051 // A list item that appears in the inclusive or exclusive clause must appear
19052 // in a reduction clause with the inscan modifier on the enclosing
19053 // worksharing-loop, worksharing-loop SIMD, or simd construct.
19054 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
19055 DVar.Modifier != OMPC_REDUCTION_inscan) {
19056 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
19057 << RefExpr->getSourceRange();
19058 } else {
19059 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->markDeclAsUsedInScanDirective(D);
19060 }
19061 Vars.push_back(RefExpr);
19062 }
19063
19064 if (Vars.empty())
19065 return nullptr;
19066
19067 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19068}
19069
19070/// Tries to find omp_alloctrait_t type.
19071static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19072 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19073 if (!OMPAlloctraitT.isNull())
19074 return true;
19075 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19076 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19077 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19078 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19079 return false;
19080 }
19081 Stack->setOMPAlloctraitT(PT.get());
19082 return true;
19083}
19084
19085OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19086 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19087 ArrayRef<UsesAllocatorsData> Data) {
19088 // OpenMP [2.12.5, target Construct]
19089 // allocator is an identifier of omp_allocator_handle_t type.
19090 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19091 return nullptr;
19092 // OpenMP [2.12.5, target Construct]
19093 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19094 if (llvm::any_of(
19095 Data,
19096 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19097 !findOMPAlloctraitT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
19098 return nullptr;
19099 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19100 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19101 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19102 StringRef Allocator =
19103 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19104 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19105 PredefinedAllocators.insert(LookupSingleName(
19106 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19107 }
19108
19109 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19110 for (const UsesAllocatorsData &D : Data) {
19111 Expr *AllocatorExpr = nullptr;
19112 // Check allocator expression.
19113 if (D.Allocator->isTypeDependent()) {
19114 AllocatorExpr = D.Allocator;
19115 } else {
19116 // Traits were specified - need to assign new allocator to the specified
19117 // allocator, so it must be an lvalue.
19118 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19119 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19120 bool IsPredefinedAllocator = false;
19121 if (DRE)
19122 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19123 if (!DRE ||
19124 !(Context.hasSameUnqualifiedType(
19125 AllocatorExpr->getType(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT()) ||
19126 Context.typesAreCompatible(AllocatorExpr->getType(),
19127 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
19128 /*CompareUnqualified=*/true)) ||
19129 (!IsPredefinedAllocator &&
19130 (AllocatorExpr->getType().isConstant(Context) ||
19131 !AllocatorExpr->isLValue()))) {
19132 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19133 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19134 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19135 continue;
19136 }
19137 // OpenMP [2.12.5, target Construct]
19138 // Predefined allocators appearing in a uses_allocators clause cannot have
19139 // traits specified.
19140 if (IsPredefinedAllocator && D.AllocatorTraits) {
19141 Diag(D.AllocatorTraits->getExprLoc(),
19142 diag::err_omp_predefined_allocator_with_traits)
19143 << D.AllocatorTraits->getSourceRange();
19144 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19145 << cast<NamedDecl>(DRE->getDecl())->getName()
19146 << D.Allocator->getSourceRange();
19147 continue;
19148 }
19149 // OpenMP [2.12.5, target Construct]
19150 // Non-predefined allocators appearing in a uses_allocators clause must
19151 // have traits specified.
19152 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19153 Diag(D.Allocator->getExprLoc(),
19154 diag::err_omp_nonpredefined_allocator_without_traits);
19155 continue;
19156 }
19157 // No allocator traits - just convert it to rvalue.
19158 if (!D.AllocatorTraits)
19159 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19160 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19161 DRE->getDecl(),
19162 IsPredefinedAllocator
19163 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19164 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19165 }
19166 Expr *AllocatorTraitsExpr = nullptr;
19167 if (D.AllocatorTraits) {
19168 if (D.AllocatorTraits->isTypeDependent()) {
19169 AllocatorTraitsExpr = D.AllocatorTraits;
19170 } else {
19171 // OpenMP [2.12.5, target Construct]
19172 // Arrays that contain allocator traits that appear in a uses_allocators
19173 // clause must be constant arrays, have constant values and be defined
19174 // in the same scope as the construct in which the clause appears.
19175 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19176 // Check that traits expr is a constant array.
19177 QualType TraitTy;
19178 if (const ArrayType *Ty =
19179 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19180 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19181 TraitTy = ConstArrayTy->getElementType();
19182 if (TraitTy.isNull() ||
19183 !(Context.hasSameUnqualifiedType(TraitTy,
19184 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT()) ||
19185 Context.typesAreCompatible(TraitTy, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAlloctraitT(),
19186 /*CompareUnqualified=*/true))) {
19187 Diag(D.AllocatorTraits->getExprLoc(),
19188 diag::err_omp_expected_array_alloctraits)
19189 << AllocatorTraitsExpr->getType();
19190 continue;
19191 }
19192 // Do not map by default allocator traits if it is a standalone
19193 // variable.
19194 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19195 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUsesAllocatorsDecl(
19196 DRE->getDecl(),
19197 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19198 }
19199 }
19200 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19201 NewD.Allocator = AllocatorExpr;
19202 NewD.AllocatorTraits = AllocatorTraitsExpr;
19203 NewD.LParenLoc = D.LParenLoc;
19204 NewD.RParenLoc = D.RParenLoc;
19205 }
19206 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19207 NewData);
19208}
19209
19210OMPClause *Sema::ActOnOpenMPAffinityClause(
19211 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19212 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19213 SmallVector<Expr *, 8> Vars;
19214 for (Expr *RefExpr : Locators) {
19215 assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast
<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-12~++20200806111125+5446ec85070/clang/lib/Sema/SemaOpenMP.cpp"
, 19215, __PRETTY_FUNCTION__))
;
19216 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19217 // It will be analyzed later.
19218 Vars.push_back(RefExpr);
19219 continue;
19220 }
19221
19222 SourceLocation ELoc = RefExpr->getExprLoc();
19223 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19224
19225 if (!SimpleExpr->isLValue()) {
19226 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19227 << 1 << 0 << RefExpr->getSourceRange();
19228 continue;
19229 }
19230
19231 ExprResult Res;
19232 {
19233 Sema::TentativeAnalysisScope Trap(*this);
19234 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19235 }
19236 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19237 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19238 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19239 << 1 << 0 << RefExpr->getSourceRange();
19240 continue;
19241 }
19242 Vars.push_back(SimpleExpr);
19243 }
19244
19245 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19246 EndLoc, Modifier, Vars);
19247}