Bug Summary

File:clang/lib/Sema/SemaOpenMP.cpp
Warning:line 6391, column 7
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -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 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.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-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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-11/lib/clang/11.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-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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/StmtCXX.h"
22#include "clang/AST/StmtOpenMP.h"
23#include "clang/AST/StmtVisitor.h"
24#include "clang/AST/TypeOrdering.h"
25#include "clang/Basic/DiagnosticSema.h"
26#include "clang/Basic/OpenMPKinds.h"
27#include "clang/Basic/PartialDiagnostic.h"
28#include "clang/Sema/Initialization.h"
29#include "clang/Sema/Lookup.h"
30#include "clang/Sema/Scope.h"
31#include "clang/Sema/ScopeInfo.h"
32#include "clang/Sema/SemaInternal.h"
33#include "llvm/ADT/IndexedMap.h"
34#include "llvm/ADT/PointerEmbeddedInt.h"
35#include "llvm/ADT/STLExtras.h"
36#include "llvm/Frontend/OpenMP/OMPConstants.h"
37using namespace clang;
38using namespace llvm::omp;
39
40//===----------------------------------------------------------------------===//
41// Stack of data-sharing attributes for variables
42//===----------------------------------------------------------------------===//
43
44static const Expr *checkMapClauseExpressionBase(
45 Sema &SemaRef, Expr *E,
46 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
47 OpenMPClauseKind CKind, bool NoDiagnose);
48
49namespace {
50/// Default data sharing attributes, which can be applied to directive.
51enum DefaultDataSharingAttributes {
52 DSA_unspecified = 0, /// Data sharing attribute not specified.
53 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
54 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
55};
56
57/// Stack for tracking declarations used in OpenMP directives and
58/// clauses and their data-sharing attributes.
59class DSAStackTy {
60public:
61 struct DSAVarData {
62 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
64 const Expr *RefExpr = nullptr;
65 DeclRefExpr *PrivateCopy = nullptr;
66 SourceLocation ImplicitDSALoc;
67 DSAVarData() = default;
68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70 SourceLocation ImplicitDSALoc)
71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73 };
74 using OperatorOffsetTy =
75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
76 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78
79private:
80 struct DSAInfo {
81 OpenMPClauseKind Attributes = OMPC_unknown;
82 /// Pointer to a reference expression and a flag which shows that the
83 /// variable is marked as lastprivate(true) or not (false).
84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85 DeclRefExpr *PrivateCopy = nullptr;
86 };
87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92 /// Struct that associates a component with the clause kind where they are
93 /// found.
94 struct MappedExprComponentTy {
95 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96 OpenMPClauseKind Kind = OMPC_unknown;
97 };
98 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102 struct ReductionData {
103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104 SourceRange ReductionRange;
105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106 ReductionData() = default;
107 void set(BinaryOperatorKind BO, SourceRange RR) {
108 ReductionRange = RR;
109 ReductionOp = BO;
110 }
111 void set(const Expr *RefExpr, SourceRange RR) {
112 ReductionRange = RR;
113 ReductionOp = RefExpr;
114 }
115 };
116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118 struct DefaultmapInfo {
119 OpenMPDefaultmapClauseModifier ImplicitBehavior =
120 OMPC_DEFAULTMAP_MODIFIER_unknown;
121 SourceLocation SLoc;
122 DefaultmapInfo() = default;
123 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
124 : ImplicitBehavior(M), SLoc(Loc) {}
125 };
126
127 struct SharingMapTy {
128 DeclSAMapTy SharingMap;
129 DeclReductionMapTy ReductionMap;
130 UsedRefMapTy AlignedMap;
131 UsedRefMapTy NontemporalMap;
132 MappedExprComponentsTy MappedExprComponents;
133 LoopControlVariablesMapTy LCVMap;
134 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
135 SourceLocation DefaultAttrLoc;
136 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
137 OpenMPDirectiveKind Directive = OMPD_unknown;
138 DeclarationNameInfo DirectiveName;
139 Scope *CurScope = nullptr;
140 SourceLocation ConstructLoc;
141 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
142 /// get the data (loop counters etc.) about enclosing loop-based construct.
143 /// This data is required during codegen.
144 DoacrossDependMapTy DoacrossDepends;
145 /// First argument (Expr *) contains optional argument of the
146 /// 'ordered' clause, the second one is true if the regions has 'ordered'
147 /// clause, false otherwise.
148 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
149 unsigned AssociatedLoops = 1;
150 bool HasMutipleLoops = false;
151 const Decl *PossiblyLoopCounter = nullptr;
152 bool NowaitRegion = false;
153 bool CancelRegion = false;
154 bool LoopStart = false;
155 bool BodyComplete = false;
156 SourceLocation InnerTeamsRegionLoc;
157 /// Reference to the taskgroup task_reduction reference expression.
158 Expr *TaskgroupReductionRef = nullptr;
159 llvm::DenseSet<QualType> MappedClassesQualTypes;
160 SmallVector<Expr *, 4> InnerUsedAllocators;
161 /// List of globals marked as declare target link in this target region
162 /// (isOpenMPTargetExecutionDirective(Directive) == true).
163 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
164 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
165 Scope *CurScope, SourceLocation Loc)
166 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
167 ConstructLoc(Loc) {}
168 SharingMapTy() = default;
169 };
170
171 using StackTy = SmallVector<SharingMapTy, 4>;
172
173 /// Stack of used declaration and their data-sharing attributes.
174 DeclSAMapTy Threadprivates;
175 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
176 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
177 /// true, if check for DSA must be from parent directive, false, if
178 /// from current directive.
179 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
180 Sema &SemaRef;
181 bool ForceCapturing = false;
182 /// true if all the variables in the target executable directives must be
183 /// captured by reference.
184 bool ForceCaptureByReferenceInTargetExecutable = false;
185 CriticalsWithHintsTy Criticals;
186 unsigned IgnoredStackElements = 0;
187
188 /// Iterators over the stack iterate in order from innermost to outermost
189 /// directive.
190 using const_iterator = StackTy::const_reverse_iterator;
191 const_iterator begin() const {
192 return Stack.empty() ? const_iterator()
193 : Stack.back().first.rbegin() + IgnoredStackElements;
194 }
195 const_iterator end() const {
196 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
197 }
198 using iterator = StackTy::reverse_iterator;
199 iterator begin() {
200 return Stack.empty() ? iterator()
201 : Stack.back().first.rbegin() + IgnoredStackElements;
202 }
203 iterator end() {
204 return Stack.empty() ? iterator() : Stack.back().first.rend();
205 }
206
207 // Convenience operations to get at the elements of the stack.
208
209 bool isStackEmpty() const {
210 return Stack.empty() ||
211 Stack.back().second != CurrentNonCapturingFunctionScope ||
212 Stack.back().first.size() <= IgnoredStackElements;
213 }
214 size_t getStackSize() const {
215 return isStackEmpty() ? 0
216 : Stack.back().first.size() - IgnoredStackElements;
217 }
218
219 SharingMapTy *getTopOfStackOrNull() {
220 size_t Size = getStackSize();
221 if (Size == 0)
222 return nullptr;
223 return &Stack.back().first[Size - 1];
224 }
225 const SharingMapTy *getTopOfStackOrNull() const {
226 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
227 }
228 SharingMapTy &getTopOfStack() {
229 assert(!isStackEmpty() && "no current directive")((!isStackEmpty() && "no current directive") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && \"no current directive\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 229, __PRETTY_FUNCTION__))
;
230 return *getTopOfStackOrNull();
231 }
232 const SharingMapTy &getTopOfStack() const {
233 return const_cast<DSAStackTy&>(*this).getTopOfStack();
234 }
235
236 SharingMapTy *getSecondOnStackOrNull() {
237 size_t Size = getStackSize();
238 if (Size <= 1)
239 return nullptr;
240 return &Stack.back().first[Size - 2];
241 }
242 const SharingMapTy *getSecondOnStackOrNull() const {
243 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
244 }
245
246 /// Get the stack element at a certain level (previously returned by
247 /// \c getNestingLevel).
248 ///
249 /// Note that nesting levels count from outermost to innermost, and this is
250 /// the reverse of our iteration order where new inner levels are pushed at
251 /// the front of the stack.
252 SharingMapTy &getStackElemAtLevel(unsigned Level) {
253 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 253, __PRETTY_FUNCTION__))
;
254 return Stack.back().first[Level];
255 }
256 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
257 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
258 }
259
260 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
261
262 /// Checks if the variable is a local for OpenMP region.
263 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
264
265 /// Vector of previously declared requires directives
266 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
267 /// omp_allocator_handle_t type.
268 QualType OMPAllocatorHandleT;
269 /// omp_depend_t type.
270 QualType OMPDependT;
271 /// Expression for the predefined allocators.
272 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
273 nullptr};
274 /// Vector of previously encountered target directives
275 SmallVector<SourceLocation, 2> TargetLocations;
276 SourceLocation AtomicLocation;
277
278public:
279 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
280
281 /// Sets omp_allocator_handle_t type.
282 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
283 /// Gets omp_allocator_handle_t type.
284 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
285 /// Sets the given default allocator.
286 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
287 Expr *Allocator) {
288 OMPPredefinedAllocators[AllocatorKind] = Allocator;
289 }
290 /// Returns the specified default allocator.
291 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
292 return OMPPredefinedAllocators[AllocatorKind];
293 }
294 /// Sets omp_depend_t type.
295 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
296 /// Gets omp_depend_t type.
297 QualType getOMPDependT() const { return OMPDependT; }
298
299 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
300 OpenMPClauseKind getClauseParsingMode() const {
301 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 301, __PRETTY_FUNCTION__))
;
302 return ClauseKindMode;
303 }
304 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
305
306 bool isBodyComplete() const {
307 const SharingMapTy *Top = getTopOfStackOrNull();
308 return Top && Top->BodyComplete;
309 }
310 void setBodyComplete() {
311 getTopOfStack().BodyComplete = true;
312 }
313
314 bool isForceVarCapturing() const { return ForceCapturing; }
315 void setForceVarCapturing(bool V) { ForceCapturing = V; }
316
317 void setForceCaptureByReferenceInTargetExecutable(bool V) {
318 ForceCaptureByReferenceInTargetExecutable = V;
319 }
320 bool isForceCaptureByReferenceInTargetExecutable() const {
321 return ForceCaptureByReferenceInTargetExecutable;
322 }
323
324 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
325 Scope *CurScope, SourceLocation Loc) {
326 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 327, __PRETTY_FUNCTION__))
327 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 327, __PRETTY_FUNCTION__))
;
328 if (Stack.empty() ||
329 Stack.back().second != CurrentNonCapturingFunctionScope)
330 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
331 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
332 Stack.back().first.back().DefaultAttrLoc = Loc;
333 }
334
335 void pop() {
336 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 337, __PRETTY_FUNCTION__))
337 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 337, __PRETTY_FUNCTION__))
;
338 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 339, __PRETTY_FUNCTION__))
339 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 339, __PRETTY_FUNCTION__))
;
340 Stack.back().first.pop_back();
341 }
342
343 /// RAII object to temporarily leave the scope of a directive when we want to
344 /// logically operate in its parent.
345 class ParentDirectiveScope {
346 DSAStackTy &Self;
347 bool Active;
348 public:
349 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
350 : Self(Self), Active(false) {
351 if (Activate)
352 enable();
353 }
354 ~ParentDirectiveScope() { disable(); }
355 void disable() {
356 if (Active) {
357 --Self.IgnoredStackElements;
358 Active = false;
359 }
360 }
361 void enable() {
362 if (!Active) {
363 ++Self.IgnoredStackElements;
364 Active = true;
365 }
366 }
367 };
368
369 /// Marks that we're started loop parsing.
370 void loopInit() {
371 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 372, __PRETTY_FUNCTION__))
372 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 372, __PRETTY_FUNCTION__))
;
373 getTopOfStack().LoopStart = true;
374 }
375 /// Start capturing of the variables in the loop context.
376 void loopStart() {
377 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 378, __PRETTY_FUNCTION__))
378 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 378, __PRETTY_FUNCTION__))
;
379 getTopOfStack().LoopStart = false;
380 }
381 /// true, if variables are captured, false otherwise.
382 bool isLoopStarted() const {
383 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 384, __PRETTY_FUNCTION__))
384 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 384, __PRETTY_FUNCTION__))
;
385 return !getTopOfStack().LoopStart;
386 }
387 /// Marks (or clears) declaration as possibly loop counter.
388 void resetPossibleLoopCounter(const Decl *D = nullptr) {
389 getTopOfStack().PossiblyLoopCounter =
390 D ? D->getCanonicalDecl() : D;
391 }
392 /// Gets the possible loop counter decl.
393 const Decl *getPossiblyLoopCunter() const {
394 return getTopOfStack().PossiblyLoopCounter;
395 }
396 /// Start new OpenMP region stack in new non-capturing function.
397 void pushFunction() {
398 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 399, __PRETTY_FUNCTION__))
399 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 399, __PRETTY_FUNCTION__))
;
400 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
401 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 401, __PRETTY_FUNCTION__))
;
402 CurrentNonCapturingFunctionScope = CurFnScope;
403 }
404 /// Pop region stack for non-capturing function.
405 void popFunction(const FunctionScopeInfo *OldFSI) {
406 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 407, __PRETTY_FUNCTION__))
407 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 407, __PRETTY_FUNCTION__))
;
408 if (!Stack.empty() && Stack.back().second == OldFSI) {
409 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 409, __PRETTY_FUNCTION__))
;
410 Stack.pop_back();
411 }
412 CurrentNonCapturingFunctionScope = nullptr;
413 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
414 if (!isa<CapturingScopeInfo>(FSI)) {
415 CurrentNonCapturingFunctionScope = FSI;
416 break;
417 }
418 }
419 }
420
421 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
422 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
423 }
424 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
425 getCriticalWithHint(const DeclarationNameInfo &Name) const {
426 auto I = Criticals.find(Name.getAsString());
427 if (I != Criticals.end())
428 return I->second;
429 return std::make_pair(nullptr, llvm::APSInt());
430 }
431 /// If 'aligned' declaration for given variable \a D was not seen yet,
432 /// add it and return NULL; otherwise return previous occurrence's expression
433 /// for diagnostics.
434 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
435 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
436 /// add it and return NULL; otherwise return previous occurrence's expression
437 /// for diagnostics.
438 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
439
440 /// Register specified variable as loop control variable.
441 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
442 /// Check if the specified variable is a loop control variable for
443 /// current region.
444 /// \return The index of the loop control variable in the list of associated
445 /// for-loops (from outer to inner).
446 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
447 /// Check if the specified variable is a loop control variable for
448 /// parent region.
449 /// \return The index of the loop control variable in the list of associated
450 /// for-loops (from outer to inner).
451 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
452 /// Get the loop control variable for the I-th loop (or nullptr) in
453 /// parent directive.
454 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
455
456 /// Adds explicit data sharing attribute to the specified declaration.
457 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
458 DeclRefExpr *PrivateCopy = nullptr);
459
460 /// Adds additional information for the reduction items with the reduction id
461 /// represented as an operator.
462 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
463 BinaryOperatorKind BOK);
464 /// Adds additional information for the reduction items with the reduction id
465 /// represented as reduction identifier.
466 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
467 const Expr *ReductionRef);
468 /// Returns the location and reduction operation from the innermost parent
469 /// region for the given \p D.
470 const DSAVarData
471 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
472 BinaryOperatorKind &BOK,
473 Expr *&TaskgroupDescriptor) const;
474 /// Returns the location and reduction operation from the innermost parent
475 /// region for the given \p D.
476 const DSAVarData
477 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
478 const Expr *&ReductionRef,
479 Expr *&TaskgroupDescriptor) const;
480 /// Return reduction reference expression for the current taskgroup.
481 Expr *getTaskgroupReductionRef() const {
482 assert(getTopOfStack().Directive == OMPD_taskgroup &&((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 484, __PRETTY_FUNCTION__))
483 "taskgroup reference expression requested for non taskgroup "((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 484, __PRETTY_FUNCTION__))
484 "directive.")((getTopOfStack().Directive == OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"getTopOfStack().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 484, __PRETTY_FUNCTION__))
;
485 return getTopOfStack().TaskgroupReductionRef;
486 }
487 /// Checks if the given \p VD declaration is actually a taskgroup reduction
488 /// descriptor variable at the \p Level of OpenMP regions.
489 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
490 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
491 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
492 ->getDecl() == VD;
493 }
494
495 /// Returns data sharing attributes from top of the stack for the
496 /// specified declaration.
497 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
498 /// Returns data-sharing attributes for the specified declaration.
499 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
500 /// Checks if the specified variables has data-sharing attributes which
501 /// match specified \a CPred predicate in any directive which matches \a DPred
502 /// predicate.
503 const DSAVarData
504 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
506 bool FromParent) const;
507 /// Checks if the specified variables has data-sharing attributes which
508 /// match specified \a CPred predicate in any innermost directive which
509 /// matches \a DPred predicate.
510 const DSAVarData
511 hasInnermostDSA(ValueDecl *D,
512 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
513 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
514 bool FromParent) const;
515 /// Checks if the specified variables has explicit data-sharing
516 /// attributes which match specified \a CPred predicate at the specified
517 /// OpenMP region.
518 bool hasExplicitDSA(const ValueDecl *D,
519 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
520 unsigned Level, bool NotLastprivate = false) const;
521
522 /// Returns true if the directive at level \Level matches in the
523 /// specified \a DPred predicate.
524 bool hasExplicitDirective(
525 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
526 unsigned Level) const;
527
528 /// Finds a directive which matches specified \a DPred predicate.
529 bool hasDirective(
530 const llvm::function_ref<bool(
531 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
532 DPred,
533 bool FromParent) const;
534
535 /// Returns currently analyzed directive.
536 OpenMPDirectiveKind getCurrentDirective() const {
537 const SharingMapTy *Top = getTopOfStackOrNull();
538 return Top ? Top->Directive : OMPD_unknown;
539 }
540 /// Returns directive kind at specified level.
541 OpenMPDirectiveKind getDirective(unsigned Level) const {
542 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 542, __PRETTY_FUNCTION__))
;
543 return getStackElemAtLevel(Level).Directive;
544 }
545 /// Returns the capture region at the specified level.
546 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
547 unsigned OpenMPCaptureLevel) const {
548 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
549 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
550 return CaptureRegions[OpenMPCaptureLevel];
551 }
552 /// Returns parent directive.
553 OpenMPDirectiveKind getParentDirective() const {
554 const SharingMapTy *Parent = getSecondOnStackOrNull();
555 return Parent ? Parent->Directive : OMPD_unknown;
556 }
557
558 /// Add requires decl to internal vector
559 void addRequiresDecl(OMPRequiresDecl *RD) {
560 RequiresDecls.push_back(RD);
561 }
562
563 /// Checks if the defined 'requires' directive has specified type of clause.
564 template <typename ClauseType>
565 bool hasRequiresDeclWithClause() const {
566 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
567 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
568 return isa<ClauseType>(C);
569 });
570 });
571 }
572
573 /// Checks for a duplicate clause amongst previously declared requires
574 /// directives
575 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
576 bool IsDuplicate = false;
577 for (OMPClause *CNew : ClauseList) {
578 for (const OMPRequiresDecl *D : RequiresDecls) {
579 for (const OMPClause *CPrev : D->clauselists()) {
580 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
581 SemaRef.Diag(CNew->getBeginLoc(),
582 diag::err_omp_requires_clause_redeclaration)
583 << getOpenMPClauseName(CNew->getClauseKind());
584 SemaRef.Diag(CPrev->getBeginLoc(),
585 diag::note_omp_requires_previous_clause)
586 << getOpenMPClauseName(CPrev->getClauseKind());
587 IsDuplicate = true;
588 }
589 }
590 }
591 }
592 return IsDuplicate;
593 }
594
595 /// Add location of previously encountered target to internal vector
596 void addTargetDirLocation(SourceLocation LocStart) {
597 TargetLocations.push_back(LocStart);
598 }
599
600 /// Add location for the first encountered atomicc directive.
601 void addAtomicDirectiveLoc(SourceLocation Loc) {
602 if (AtomicLocation.isInvalid())
603 AtomicLocation = Loc;
604 }
605
606 /// Returns the location of the first encountered atomic directive in the
607 /// module.
608 SourceLocation getAtomicDirectiveLoc() const {
609 return AtomicLocation;
610 }
611
612 // Return previously encountered target region locations.
613 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
614 return TargetLocations;
615 }
616
617 /// Set default data sharing attribute to none.
618 void setDefaultDSANone(SourceLocation Loc) {
619 getTopOfStack().DefaultAttr = DSA_none;
620 getTopOfStack().DefaultAttrLoc = Loc;
621 }
622 /// Set default data sharing attribute to shared.
623 void setDefaultDSAShared(SourceLocation Loc) {
624 getTopOfStack().DefaultAttr = DSA_shared;
625 getTopOfStack().DefaultAttrLoc = Loc;
626 }
627 /// Set default data mapping attribute to Modifier:Kind
628 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
629 OpenMPDefaultmapClauseKind Kind,
630 SourceLocation Loc) {
631 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
632 DMI.ImplicitBehavior = M;
633 DMI.SLoc = Loc;
634 }
635 /// Check whether the implicit-behavior has been set in defaultmap
636 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
637 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
638 OMPC_DEFAULTMAP_MODIFIER_unknown;
639 }
640
641 DefaultDataSharingAttributes getDefaultDSA() const {
642 return isStackEmpty() ? DSA_unspecified
643 : getTopOfStack().DefaultAttr;
644 }
645 SourceLocation getDefaultDSALocation() const {
646 return isStackEmpty() ? SourceLocation()
647 : getTopOfStack().DefaultAttrLoc;
648 }
649 OpenMPDefaultmapClauseModifier
650 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
651 return isStackEmpty()
652 ? OMPC_DEFAULTMAP_MODIFIER_unknown
653 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
654 }
655 OpenMPDefaultmapClauseModifier
656 getDefaultmapModifierAtLevel(unsigned Level,
657 OpenMPDefaultmapClauseKind Kind) const {
658 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
659 }
660 bool isDefaultmapCapturedByRef(unsigned Level,
661 OpenMPDefaultmapClauseKind Kind) const {
662 OpenMPDefaultmapClauseModifier M =
663 getDefaultmapModifierAtLevel(Level, Kind);
664 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
665 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
666 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
667 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
668 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
669 }
670 return true;
671 }
672 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
673 OpenMPDefaultmapClauseKind Kind) {
674 switch (Kind) {
675 case OMPC_DEFAULTMAP_scalar:
676 case OMPC_DEFAULTMAP_pointer:
677 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
678 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
679 (M == OMPC_DEFAULTMAP_MODIFIER_default);
680 case OMPC_DEFAULTMAP_aggregate:
681 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
682 default:
683 break;
684 }
685 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum")::llvm::llvm_unreachable_internal("Unexpected OpenMPDefaultmapClauseKind enum"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 685)
;
686 }
687 bool mustBeFirstprivateAtLevel(unsigned Level,
688 OpenMPDefaultmapClauseKind Kind) const {
689 OpenMPDefaultmapClauseModifier M =
690 getDefaultmapModifierAtLevel(Level, Kind);
691 return mustBeFirstprivateBase(M, Kind);
692 }
693 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
694 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
695 return mustBeFirstprivateBase(M, Kind);
696 }
697
698 /// Checks if the specified variable is a threadprivate.
699 bool isThreadPrivate(VarDecl *D) {
700 const DSAVarData DVar = getTopDSA(D, false);
701 return isOpenMPThreadPrivate(DVar.CKind);
702 }
703
704 /// Marks current region as ordered (it has an 'ordered' clause).
705 void setOrderedRegion(bool IsOrdered, const Expr *Param,
706 OMPOrderedClause *Clause) {
707 if (IsOrdered)
708 getTopOfStack().OrderedRegion.emplace(Param, Clause);
709 else
710 getTopOfStack().OrderedRegion.reset();
711 }
712 /// Returns true, if region is ordered (has associated 'ordered' clause),
713 /// false - otherwise.
714 bool isOrderedRegion() const {
715 if (const SharingMapTy *Top = getTopOfStackOrNull())
716 return Top->OrderedRegion.hasValue();
717 return false;
718 }
719 /// Returns optional parameter for the ordered region.
720 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
721 if (const SharingMapTy *Top = getTopOfStackOrNull())
722 if (Top->OrderedRegion.hasValue())
723 return Top->OrderedRegion.getValue();
724 return std::make_pair(nullptr, nullptr);
725 }
726 /// Returns true, if parent region is ordered (has associated
727 /// 'ordered' clause), false - otherwise.
728 bool isParentOrderedRegion() const {
729 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
730 return Parent->OrderedRegion.hasValue();
731 return false;
732 }
733 /// Returns optional parameter for the ordered region.
734 std::pair<const Expr *, OMPOrderedClause *>
735 getParentOrderedRegionParam() const {
736 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
737 if (Parent->OrderedRegion.hasValue())
738 return Parent->OrderedRegion.getValue();
739 return std::make_pair(nullptr, nullptr);
740 }
741 /// Marks current region as nowait (it has a 'nowait' clause).
742 void setNowaitRegion(bool IsNowait = true) {
743 getTopOfStack().NowaitRegion = IsNowait;
744 }
745 /// Returns true, if parent region is nowait (has associated
746 /// 'nowait' clause), false - otherwise.
747 bool isParentNowaitRegion() const {
748 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
749 return Parent->NowaitRegion;
750 return false;
751 }
752 /// Marks parent region as cancel region.
753 void setParentCancelRegion(bool Cancel = true) {
754 if (SharingMapTy *Parent = getSecondOnStackOrNull())
755 Parent->CancelRegion |= Cancel;
756 }
757 /// Return true if current region has inner cancel construct.
758 bool isCancelRegion() const {
759 const SharingMapTy *Top = getTopOfStackOrNull();
760 return Top ? Top->CancelRegion : false;
761 }
762
763 /// Set collapse value for the region.
764 void setAssociatedLoops(unsigned Val) {
765 getTopOfStack().AssociatedLoops = Val;
766 if (Val > 1)
767 getTopOfStack().HasMutipleLoops = true;
768 }
769 /// Return collapse value for region.
770 unsigned getAssociatedLoops() const {
771 const SharingMapTy *Top = getTopOfStackOrNull();
772 return Top ? Top->AssociatedLoops : 0;
773 }
774 /// Returns true if the construct is associated with multiple loops.
775 bool hasMutipleLoops() const {
776 const SharingMapTy *Top = getTopOfStackOrNull();
777 return Top ? Top->HasMutipleLoops : false;
778 }
779
780 /// Marks current target region as one with closely nested teams
781 /// region.
782 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
783 if (SharingMapTy *Parent = getSecondOnStackOrNull())
784 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
785 }
786 /// Returns true, if current region has closely nested teams region.
787 bool hasInnerTeamsRegion() const {
788 return getInnerTeamsRegionLoc().isValid();
789 }
790 /// Returns location of the nested teams region (if any).
791 SourceLocation getInnerTeamsRegionLoc() const {
792 const SharingMapTy *Top = getTopOfStackOrNull();
793 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
794 }
795
796 Scope *getCurScope() const {
797 const SharingMapTy *Top = getTopOfStackOrNull();
798 return Top ? Top->CurScope : nullptr;
799 }
800 SourceLocation getConstructLoc() const {
801 const SharingMapTy *Top = getTopOfStackOrNull();
802 return Top ? Top->ConstructLoc : SourceLocation();
803 }
804
805 /// Do the check specified in \a Check to all component lists and return true
806 /// if any issue is found.
807 bool checkMappableExprComponentListsForDecl(
808 const ValueDecl *VD, bool CurrentRegionOnly,
809 const llvm::function_ref<
810 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
811 OpenMPClauseKind)>
812 Check) const {
813 if (isStackEmpty())
814 return false;
815 auto SI = begin();
816 auto SE = end();
817
818 if (SI == SE)
819 return false;
820
821 if (CurrentRegionOnly)
822 SE = std::next(SI);
823 else
824 std::advance(SI, 1);
825
826 for (; SI != SE; ++SI) {
827 auto MI = SI->MappedExprComponents.find(VD);
828 if (MI != SI->MappedExprComponents.end())
829 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
830 MI->second.Components)
831 if (Check(L, MI->second.Kind))
832 return true;
833 }
834 return false;
835 }
836
837 /// Do the check specified in \a Check to all component lists at a given level
838 /// and return true if any issue is found.
839 bool checkMappableExprComponentListsForDeclAtLevel(
840 const ValueDecl *VD, unsigned Level,
841 const llvm::function_ref<
842 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
843 OpenMPClauseKind)>
844 Check) const {
845 if (getStackSize() <= Level)
846 return false;
847
848 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
849 auto MI = StackElem.MappedExprComponents.find(VD);
850 if (MI != StackElem.MappedExprComponents.end())
851 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
852 MI->second.Components)
853 if (Check(L, MI->second.Kind))
854 return true;
855 return false;
856 }
857
858 /// Create a new mappable expression component list associated with a given
859 /// declaration and initialize it with the provided list of components.
860 void addMappableExpressionComponents(
861 const ValueDecl *VD,
862 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
863 OpenMPClauseKind WhereFoundClauseKind) {
864 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
865 // Create new entry and append the new components there.
866 MEC.Components.resize(MEC.Components.size() + 1);
867 MEC.Components.back().append(Components.begin(), Components.end());
868 MEC.Kind = WhereFoundClauseKind;
869 }
870
871 unsigned getNestingLevel() const {
872 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 872, __PRETTY_FUNCTION__))
;
873 return getStackSize() - 1;
874 }
875 void addDoacrossDependClause(OMPDependClause *C,
876 const OperatorOffsetTy &OpsOffs) {
877 SharingMapTy *Parent = getSecondOnStackOrNull();
878 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive))((Parent && isOpenMPWorksharingDirective(Parent->Directive
)) ? static_cast<void> (0) : __assert_fail ("Parent && isOpenMPWorksharingDirective(Parent->Directive)"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 878, __PRETTY_FUNCTION__))
;
879 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
880 }
881 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
882 getDoacrossDependClauses() const {
883 const SharingMapTy &StackElem = getTopOfStack();
884 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
885 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
886 return llvm::make_range(Ref.begin(), Ref.end());
887 }
888 return llvm::make_range(StackElem.DoacrossDepends.end(),
889 StackElem.DoacrossDepends.end());
890 }
891
892 // Store types of classes which have been explicitly mapped
893 void addMappedClassesQualTypes(QualType QT) {
894 SharingMapTy &StackElem = getTopOfStack();
895 StackElem.MappedClassesQualTypes.insert(QT);
896 }
897
898 // Return set of mapped classes types
899 bool isClassPreviouslyMapped(QualType QT) const {
900 const SharingMapTy &StackElem = getTopOfStack();
901 return StackElem.MappedClassesQualTypes.count(QT) != 0;
902 }
903
904 /// Adds global declare target to the parent target region.
905 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
906 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 908, __PRETTY_FUNCTION__))
907 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 908, __PRETTY_FUNCTION__))
908 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 908, __PRETTY_FUNCTION__))
;
909 for (auto &Elem : *this) {
910 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
911 Elem.DeclareTargetLinkVarDecls.push_back(E);
912 return;
913 }
914 }
915 }
916
917 /// Returns the list of globals with declare target link if current directive
918 /// is target.
919 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
920 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 921, __PRETTY_FUNCTION__))
921 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 921, __PRETTY_FUNCTION__))
;
922 return getTopOfStack().DeclareTargetLinkVarDecls;
923 }
924
925 /// Adds list of allocators expressions.
926 void addInnerAllocatorExpr(Expr *E) {
927 getTopOfStack().InnerUsedAllocators.push_back(E);
928 }
929 /// Return list of used allocators.
930 ArrayRef<Expr *> getInnerAllocators() const {
931 return getTopOfStack().InnerUsedAllocators;
932 }
933};
934
935bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
936 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
937}
938
939bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
940 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
941 DKind == OMPD_unknown;
942}
943
944} // namespace
945
946static const Expr *getExprAsWritten(const Expr *E) {
947 if (const auto *FE = dyn_cast<FullExpr>(E))
948 E = FE->getSubExpr();
949
950 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
951 E = MTE->getSubExpr();
952
953 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
954 E = Binder->getSubExpr();
955
956 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
957 E = ICE->getSubExprAsWritten();
958 return E->IgnoreParens();
959}
960
961static Expr *getExprAsWritten(Expr *E) {
962 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
963}
964
965static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
966 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
967 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
968 D = ME->getMemberDecl();
969 const auto *VD = dyn_cast<VarDecl>(D);
970 const auto *FD = dyn_cast<FieldDecl>(D);
971 if (VD != nullptr) {
972 VD = VD->getCanonicalDecl();
973 D = VD;
974 } else {
975 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 975, __PRETTY_FUNCTION__))
;
976 FD = FD->getCanonicalDecl();
977 D = FD;
978 }
979 return D;
980}
981
982static ValueDecl *getCanonicalDecl(ValueDecl *D) {
983 return const_cast<ValueDecl *>(
984 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
985}
986
987DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
988 ValueDecl *D) const {
989 D = getCanonicalDecl(D);
990 auto *VD = dyn_cast<VarDecl>(D);
991 const auto *FD = dyn_cast<FieldDecl>(D);
992 DSAVarData DVar;
993 if (Iter == end()) {
994 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
995 // in a region but not in construct]
996 // File-scope or namespace-scope variables referenced in called routines
997 // in the region are shared unless they appear in a threadprivate
998 // directive.
999 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1000 DVar.CKind = OMPC_shared;
1001
1002 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1003 // in a region but not in construct]
1004 // Variables with static storage duration that are declared in called
1005 // routines in the region are shared.
1006 if (VD && VD->hasGlobalStorage())
1007 DVar.CKind = OMPC_shared;
1008
1009 // Non-static data members are shared by default.
1010 if (FD)
1011 DVar.CKind = OMPC_shared;
1012
1013 return DVar;
1014 }
1015
1016 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1017 // in a Construct, C/C++, predetermined, p.1]
1018 // Variables with automatic storage duration that are declared in a scope
1019 // inside the construct are private.
1020 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1021 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1022 DVar.CKind = OMPC_private;
1023 return DVar;
1024 }
1025
1026 DVar.DKind = Iter->Directive;
1027 // Explicitly specified attributes and local variables with predetermined
1028 // attributes.
1029 if (Iter->SharingMap.count(D)) {
1030 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1031 DVar.RefExpr = Data.RefExpr.getPointer();
1032 DVar.PrivateCopy = Data.PrivateCopy;
1033 DVar.CKind = Data.Attributes;
1034 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1035 return DVar;
1036 }
1037
1038 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1039 // in a Construct, C/C++, implicitly determined, p.1]
1040 // In a parallel or task construct, the data-sharing attributes of these
1041 // variables are determined by the default clause, if present.
1042 switch (Iter->DefaultAttr) {
1043 case DSA_shared:
1044 DVar.CKind = OMPC_shared;
1045 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1046 return DVar;
1047 case DSA_none:
1048 return DVar;
1049 case DSA_unspecified:
1050 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1051 // in a Construct, implicitly determined, p.2]
1052 // In a parallel construct, if no default clause is present, these
1053 // variables are shared.
1054 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1055 if ((isOpenMPParallelDirective(DVar.DKind) &&
1056 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1057 isOpenMPTeamsDirective(DVar.DKind)) {
1058 DVar.CKind = OMPC_shared;
1059 return DVar;
1060 }
1061
1062 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1063 // in a Construct, implicitly determined, p.4]
1064 // In a task construct, if no default clause is present, a variable that in
1065 // the enclosing context is determined to be shared by all implicit tasks
1066 // bound to the current team is shared.
1067 if (isOpenMPTaskingDirective(DVar.DKind)) {
1068 DSAVarData DVarTemp;
1069 const_iterator I = Iter, E = end();
1070 do {
1071 ++I;
1072 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1073 // Referenced in a Construct, implicitly determined, p.6]
1074 // In a task construct, if no default clause is present, a variable
1075 // whose data-sharing attribute is not determined by the rules above is
1076 // firstprivate.
1077 DVarTemp = getDSA(I, D);
1078 if (DVarTemp.CKind != OMPC_shared) {
1079 DVar.RefExpr = nullptr;
1080 DVar.CKind = OMPC_firstprivate;
1081 return DVar;
1082 }
1083 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1084 DVar.CKind =
1085 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1086 return DVar;
1087 }
1088 }
1089 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1090 // in a Construct, implicitly determined, p.3]
1091 // For constructs other than task, if no default clause is present, these
1092 // variables inherit their data-sharing attributes from the enclosing
1093 // context.
1094 return getDSA(++Iter, D);
1095}
1096
1097const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1098 const Expr *NewDE) {
1099 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1099, __PRETTY_FUNCTION__))
;
1100 D = getCanonicalDecl(D);
1101 SharingMapTy &StackElem = getTopOfStack();
1102 auto It = StackElem.AlignedMap.find(D);
1103 if (It == StackElem.AlignedMap.end()) {
1104 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1104, __PRETTY_FUNCTION__))
;
1105 StackElem.AlignedMap[D] = NewDE;
1106 return nullptr;
1107 }
1108 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1108, __PRETTY_FUNCTION__))
;
1109 return It->second;
1110}
1111
1112const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1113 const Expr *NewDE) {
1114 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1114, __PRETTY_FUNCTION__))
;
1115 D = getCanonicalDecl(D);
1116 SharingMapTy &StackElem = getTopOfStack();
1117 auto It = StackElem.NontemporalMap.find(D);
1118 if (It == StackElem.NontemporalMap.end()) {
1119 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1119, __PRETTY_FUNCTION__))
;
1120 StackElem.NontemporalMap[D] = NewDE;
1121 return nullptr;
1122 }
1123 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1123, __PRETTY_FUNCTION__))
;
1124 return It->second;
1125}
1126
1127void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1128 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1128, __PRETTY_FUNCTION__))
;
1129 D = getCanonicalDecl(D);
1130 SharingMapTy &StackElem = getTopOfStack();
1131 StackElem.LCVMap.try_emplace(
1132 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1133}
1134
1135const DSAStackTy::LCDeclInfo
1136DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1137 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1137, __PRETTY_FUNCTION__))
;
1138 D = getCanonicalDecl(D);
1139 const SharingMapTy &StackElem = getTopOfStack();
1140 auto It = StackElem.LCVMap.find(D);
1141 if (It != StackElem.LCVMap.end())
1142 return It->second;
1143 return {0, nullptr};
1144}
1145
1146const DSAStackTy::LCDeclInfo
1147DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1148 const SharingMapTy *Parent = getSecondOnStackOrNull();
1149 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1149, __PRETTY_FUNCTION__))
;
1150 D = getCanonicalDecl(D);
1151 auto It = Parent->LCVMap.find(D);
1152 if (It != Parent->LCVMap.end())
1153 return It->second;
1154 return {0, nullptr};
1155}
1156
1157const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1158 const SharingMapTy *Parent = getSecondOnStackOrNull();
1159 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1159, __PRETTY_FUNCTION__))
;
1160 if (Parent->LCVMap.size() < I)
1161 return nullptr;
1162 for (const auto &Pair : Parent->LCVMap)
1163 if (Pair.second.first == I)
1164 return Pair.first;
1165 return nullptr;
1166}
1167
1168void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1169 DeclRefExpr *PrivateCopy) {
1170 D = getCanonicalDecl(D);
1171 if (A == OMPC_threadprivate) {
1172 DSAInfo &Data = Threadprivates[D];
1173 Data.Attributes = A;
1174 Data.RefExpr.setPointer(E);
1175 Data.PrivateCopy = nullptr;
1176 } else {
1177 DSAInfo &Data = getTopOfStack().SharingMap[D];
1178 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1181, __PRETTY_FUNCTION__))
1179 (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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1181, __PRETTY_FUNCTION__))
1180 (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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1181, __PRETTY_FUNCTION__))
1181 (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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1181, __PRETTY_FUNCTION__))
;
1182 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1183 Data.RefExpr.setInt(/*IntVal=*/true);
1184 return;
1185 }
1186 const bool IsLastprivate =
1187 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1188 Data.Attributes = A;
1189 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1190 Data.PrivateCopy = PrivateCopy;
1191 if (PrivateCopy) {
1192 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1193 Data.Attributes = A;
1194 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1195 Data.PrivateCopy = nullptr;
1196 }
1197 }
1198}
1199
1200/// Build a variable declaration for OpenMP loop iteration variable.
1201static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1202 StringRef Name, const AttrVec *Attrs = nullptr,
1203 DeclRefExpr *OrigRef = nullptr) {
1204 DeclContext *DC = SemaRef.CurContext;
1205 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1206 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1207 auto *Decl =
1208 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1209 if (Attrs) {
1210 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1211 I != E; ++I)
1212 Decl->addAttr(*I);
1213 }
1214 Decl->setImplicit();
1215 if (OrigRef) {
1216 Decl->addAttr(
1217 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1218 }
1219 return Decl;
1220}
1221
1222static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1223 SourceLocation Loc,
1224 bool RefersToCapture = false) {
1225 D->setReferenced();
1226 D->markUsed(S.Context);
1227 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1228 SourceLocation(), D, RefersToCapture, Loc, Ty,
1229 VK_LValue);
1230}
1231
1232void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1233 BinaryOperatorKind BOK) {
1234 D = getCanonicalDecl(D);
1235 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1235, __PRETTY_FUNCTION__))
;
1236 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1238, __PRETTY_FUNCTION__))
1237 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1238, __PRETTY_FUNCTION__))
1238 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1238, __PRETTY_FUNCTION__))
;
1239 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1240 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1243, __PRETTY_FUNCTION__))
1241 getTopOfStack().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1243, __PRETTY_FUNCTION__))
1242 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1243, __PRETTY_FUNCTION__))
1243 "items.")((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1243, __PRETTY_FUNCTION__))
;
1244 ReductionData.set(BOK, SR);
1245 Expr *&TaskgroupReductionRef =
1246 getTopOfStack().TaskgroupReductionRef;
1247 if (!TaskgroupReductionRef) {
1248 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1249 SemaRef.Context.VoidPtrTy, ".task_red.");
1250 TaskgroupReductionRef =
1251 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1252 }
1253}
1254
1255void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1256 const Expr *ReductionRef) {
1257 D = getCanonicalDecl(D);
1258 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1258, __PRETTY_FUNCTION__))
;
1259 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1261, __PRETTY_FUNCTION__))
1260 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1261, __PRETTY_FUNCTION__))
1261 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1261, __PRETTY_FUNCTION__))
;
1262 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1263 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1266, __PRETTY_FUNCTION__))
1264 getTopOfStack().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1266, __PRETTY_FUNCTION__))
1265 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1266, __PRETTY_FUNCTION__))
1266 "items.")((ReductionData.ReductionRange.isInvalid() && getTopOfStack
().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<void> (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && getTopOfStack().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1266, __PRETTY_FUNCTION__))
;
1267 ReductionData.set(ReductionRef, SR);
1268 Expr *&TaskgroupReductionRef =
1269 getTopOfStack().TaskgroupReductionRef;
1270 if (!TaskgroupReductionRef) {
1271 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1272 SemaRef.Context.VoidPtrTy, ".task_red.");
1273 TaskgroupReductionRef =
1274 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1275 }
1276}
1277
1278const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1279 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1280 Expr *&TaskgroupDescriptor) const {
1281 D = getCanonicalDecl(D);
1282 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1282, __PRETTY_FUNCTION__))
;
1283 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1284 const DSAInfo &Data = I->SharingMap.lookup(D);
1285 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1286 continue;
1287 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1288 if (!ReductionData.ReductionOp ||
1289 ReductionData.ReductionOp.is<const Expr *>())
1290 return DSAVarData();
1291 SR = ReductionData.ReductionRange;
1292 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1293 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1295, __PRETTY_FUNCTION__))
1294 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1295, __PRETTY_FUNCTION__))
1295 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1295, __PRETTY_FUNCTION__))
;
1296 TaskgroupDescriptor = I->TaskgroupReductionRef;
1297 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1298 Data.PrivateCopy, I->DefaultAttrLoc);
1299 }
1300 return DSAVarData();
1301}
1302
1303const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1304 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1305 Expr *&TaskgroupDescriptor) const {
1306 D = getCanonicalDecl(D);
1307 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1307, __PRETTY_FUNCTION__))
;
1308 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1309 const DSAInfo &Data = I->SharingMap.lookup(D);
1310 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1311 continue;
1312 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1313 if (!ReductionData.ReductionOp ||
1314 !ReductionData.ReductionOp.is<const Expr *>())
1315 return DSAVarData();
1316 SR = ReductionData.ReductionRange;
1317 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1318 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1320, __PRETTY_FUNCTION__))
1319 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1320, __PRETTY_FUNCTION__))
1320 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1320, __PRETTY_FUNCTION__))
;
1321 TaskgroupDescriptor = I->TaskgroupReductionRef;
1322 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1323 Data.PrivateCopy, I->DefaultAttrLoc);
1324 }
1325 return DSAVarData();
1326}
1327
1328bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1329 D = D->getCanonicalDecl();
1330 for (const_iterator E = end(); I != E; ++I) {
1331 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1332 isOpenMPTargetExecutionDirective(I->Directive)) {
1333 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1334 Scope *CurScope = getCurScope();
1335 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1336 CurScope = CurScope->getParent();
1337 return CurScope != TopScope;
1338 }
1339 }
1340 return false;
1341}
1342
1343static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1344 bool AcceptIfMutable = true,
1345 bool *IsClassType = nullptr) {
1346 ASTContext &Context = SemaRef.getASTContext();
1347 Type = Type.getNonReferenceType().getCanonicalType();
1348 bool IsConstant = Type.isConstant(Context);
1349 Type = Context.getBaseElementType(Type);
1350 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1351 ? Type->getAsCXXRecordDecl()
1352 : nullptr;
1353 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1354 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1355 RD = CTD->getTemplatedDecl();
1356 if (IsClassType)
1357 *IsClassType = RD;
1358 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1359 RD->hasDefinition() && RD->hasMutableFields());
1360}
1361
1362static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1363 QualType Type, OpenMPClauseKind CKind,
1364 SourceLocation ELoc,
1365 bool AcceptIfMutable = true,
1366 bool ListItemNotVar = false) {
1367 ASTContext &Context = SemaRef.getASTContext();
1368 bool IsClassType;
1369 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1370 unsigned Diag = ListItemNotVar
1371 ? diag::err_omp_const_list_item
1372 : IsClassType ? diag::err_omp_const_not_mutable_variable
1373 : diag::err_omp_const_variable;
1374 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1375 if (!ListItemNotVar && D) {
1376 const VarDecl *VD = dyn_cast<VarDecl>(D);
1377 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1378 VarDecl::DeclarationOnly;
1379 SemaRef.Diag(D->getLocation(),
1380 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1381 << D;
1382 }
1383 return true;
1384 }
1385 return false;
1386}
1387
1388const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1389 bool FromParent) {
1390 D = getCanonicalDecl(D);
1391 DSAVarData DVar;
1392
1393 auto *VD = dyn_cast<VarDecl>(D);
1394 auto TI = Threadprivates.find(D);
1395 if (TI != Threadprivates.end()) {
1396 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1397 DVar.CKind = OMPC_threadprivate;
1398 return DVar;
1399 }
1400 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1401 DVar.RefExpr = buildDeclRefExpr(
1402 SemaRef, VD, D->getType().getNonReferenceType(),
1403 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1404 DVar.CKind = OMPC_threadprivate;
1405 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1406 return DVar;
1407 }
1408 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1409 // in a Construct, C/C++, predetermined, p.1]
1410 // Variables appearing in threadprivate directives are threadprivate.
1411 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1412 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1413 SemaRef.getLangOpts().OpenMPUseTLS &&
1414 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1415 (VD && VD->getStorageClass() == SC_Register &&
1416 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1417 DVar.RefExpr = buildDeclRefExpr(
1418 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1419 DVar.CKind = OMPC_threadprivate;
1420 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1421 return DVar;
1422 }
1423 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1424 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1425 !isLoopControlVariable(D).first) {
1426 const_iterator IterTarget =
1427 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1428 return isOpenMPTargetExecutionDirective(Data.Directive);
1429 });
1430 if (IterTarget != end()) {
1431 const_iterator ParentIterTarget = IterTarget + 1;
1432 for (const_iterator Iter = begin();
1433 Iter != ParentIterTarget; ++Iter) {
1434 if (isOpenMPLocal(VD, Iter)) {
1435 DVar.RefExpr =
1436 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1437 D->getLocation());
1438 DVar.CKind = OMPC_threadprivate;
1439 return DVar;
1440 }
1441 }
1442 if (!isClauseParsingMode() || IterTarget != begin()) {
1443 auto DSAIter = IterTarget->SharingMap.find(D);
1444 if (DSAIter != IterTarget->SharingMap.end() &&
1445 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1446 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1447 DVar.CKind = OMPC_threadprivate;
1448 return DVar;
1449 }
1450 const_iterator End = end();
1451 if (!SemaRef.isOpenMPCapturedByRef(
1452 D, std::distance(ParentIterTarget, End),
1453 /*OpenMPCaptureLevel=*/0)) {
1454 DVar.RefExpr =
1455 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1456 IterTarget->ConstructLoc);
1457 DVar.CKind = OMPC_threadprivate;
1458 return DVar;
1459 }
1460 }
1461 }
1462 }
1463
1464 if (isStackEmpty())
1465 // Not in OpenMP execution region and top scope was already checked.
1466 return DVar;
1467
1468 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1469 // in a Construct, C/C++, predetermined, p.4]
1470 // Static data members are shared.
1471 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1472 // in a Construct, C/C++, predetermined, p.7]
1473 // Variables with static storage duration that are declared in a scope
1474 // inside the construct are shared.
1475 if (VD && VD->isStaticDataMember()) {
1476 // Check for explicitly specified attributes.
1477 const_iterator I = begin();
1478 const_iterator EndI = end();
1479 if (FromParent && I != EndI)
1480 ++I;
1481 auto It = I->SharingMap.find(D);
1482 if (It != I->SharingMap.end()) {
1483 const DSAInfo &Data = It->getSecond();
1484 DVar.RefExpr = Data.RefExpr.getPointer();
1485 DVar.PrivateCopy = Data.PrivateCopy;
1486 DVar.CKind = Data.Attributes;
1487 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1488 DVar.DKind = I->Directive;
1489 return DVar;
1490 }
1491
1492 DVar.CKind = OMPC_shared;
1493 return DVar;
1494 }
1495
1496 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1497 // The predetermined shared attribute for const-qualified types having no
1498 // mutable members was removed after OpenMP 3.1.
1499 if (SemaRef.LangOpts.OpenMP <= 31) {
1500 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1501 // in a Construct, C/C++, predetermined, p.6]
1502 // Variables with const qualified type having no mutable member are
1503 // shared.
1504 if (isConstNotMutableType(SemaRef, D->getType())) {
1505 // Variables with const-qualified type having no mutable member may be
1506 // listed in a firstprivate clause, even if they are static data members.
1507 DSAVarData DVarTemp = hasInnermostDSA(
1508 D,
1509 [](OpenMPClauseKind C) {
1510 return C == OMPC_firstprivate || C == OMPC_shared;
1511 },
1512 MatchesAlways, FromParent);
1513 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1514 return DVarTemp;
1515
1516 DVar.CKind = OMPC_shared;
1517 return DVar;
1518 }
1519 }
1520
1521 // Explicitly specified attributes and local variables with predetermined
1522 // attributes.
1523 const_iterator I = begin();
1524 const_iterator EndI = end();
1525 if (FromParent && I != EndI)
1526 ++I;
1527 auto It = I->SharingMap.find(D);
1528 if (It != I->SharingMap.end()) {
1529 const DSAInfo &Data = It->getSecond();
1530 DVar.RefExpr = Data.RefExpr.getPointer();
1531 DVar.PrivateCopy = Data.PrivateCopy;
1532 DVar.CKind = Data.Attributes;
1533 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1534 DVar.DKind = I->Directive;
1535 }
1536
1537 return DVar;
1538}
1539
1540const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1541 bool FromParent) const {
1542 if (isStackEmpty()) {
1543 const_iterator I;
1544 return getDSA(I, D);
1545 }
1546 D = getCanonicalDecl(D);
1547 const_iterator StartI = begin();
1548 const_iterator EndI = end();
1549 if (FromParent && StartI != EndI)
1550 ++StartI;
1551 return getDSA(StartI, D);
1552}
1553
1554const DSAStackTy::DSAVarData
1555DSAStackTy::hasDSA(ValueDecl *D,
1556 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1557 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1558 bool FromParent) const {
1559 if (isStackEmpty())
1560 return {};
1561 D = getCanonicalDecl(D);
1562 const_iterator I = begin();
1563 const_iterator EndI = end();
1564 if (FromParent && I != EndI)
1565 ++I;
1566 for (; I != EndI; ++I) {
1567 if (!DPred(I->Directive) &&
1568 !isImplicitOrExplicitTaskingRegion(I->Directive))
1569 continue;
1570 const_iterator NewI = I;
1571 DSAVarData DVar = getDSA(NewI, D);
1572 if (I == NewI && CPred(DVar.CKind))
1573 return DVar;
1574 }
1575 return {};
1576}
1577
1578const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1579 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1580 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1581 bool FromParent) const {
1582 if (isStackEmpty())
1583 return {};
1584 D = getCanonicalDecl(D);
1585 const_iterator StartI = begin();
1586 const_iterator EndI = end();
1587 if (FromParent && StartI != EndI)
1588 ++StartI;
1589 if (StartI == EndI || !DPred(StartI->Directive))
1590 return {};
1591 const_iterator NewI = StartI;
1592 DSAVarData DVar = getDSA(NewI, D);
1593 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1594}
1595
1596bool DSAStackTy::hasExplicitDSA(
1597 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1598 unsigned Level, bool NotLastprivate) const {
1599 if (getStackSize() <= Level)
1600 return false;
1601 D = getCanonicalDecl(D);
1602 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1603 auto I = StackElem.SharingMap.find(D);
1604 if (I != StackElem.SharingMap.end() &&
1605 I->getSecond().RefExpr.getPointer() &&
1606 CPred(I->getSecond().Attributes) &&
1607 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1608 return true;
1609 // Check predetermined rules for the loop control variables.
1610 auto LI = StackElem.LCVMap.find(D);
1611 if (LI != StackElem.LCVMap.end())
1612 return CPred(OMPC_private);
1613 return false;
1614}
1615
1616bool DSAStackTy::hasExplicitDirective(
1617 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1618 unsigned Level) const {
1619 if (getStackSize() <= Level)
1620 return false;
1621 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1622 return DPred(StackElem.Directive);
1623}
1624
1625bool DSAStackTy::hasDirective(
1626 const llvm::function_ref<bool(OpenMPDirectiveKind,
1627 const DeclarationNameInfo &, SourceLocation)>
1628 DPred,
1629 bool FromParent) const {
1630 // We look only in the enclosing region.
1631 size_t Skip = FromParent ? 2 : 1;
1632 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1633 I != E; ++I) {
1634 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1635 return true;
1636 }
1637 return false;
1638}
1639
1640void Sema::InitDataSharingAttributesStack() {
1641 VarDataSharingAttributesStack = new DSAStackTy(*this);
1642}
1643
1644#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1645
1646void Sema::pushOpenMPFunctionRegion() {
1647 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1648}
1649
1650void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1651 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1652}
1653
1654static bool isOpenMPDeviceDelayedContext(Sema &S) {
1655 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1656, __PRETTY_FUNCTION__))
1656 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1656, __PRETTY_FUNCTION__))
;
1657 return !S.isInOpenMPTargetExecutionDirective() &&
1658 !S.isInOpenMPDeclareTargetContext();
1659}
1660
1661namespace {
1662/// Status of the function emission on the host/device.
1663enum class FunctionEmissionStatus {
1664 Emitted,
1665 Discarded,
1666 Unknown,
1667};
1668} // anonymous namespace
1669
1670Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1671 unsigned DiagID) {
1672 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1673, __PRETTY_FUNCTION__))
1673 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1673, __PRETTY_FUNCTION__))
;
1674 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1675 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1676 switch (FES) {
1677 case FunctionEmissionStatus::Emitted:
1678 Kind = DeviceDiagBuilder::K_Immediate;
1679 break;
1680 case FunctionEmissionStatus::Unknown:
1681 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred
1682 : DeviceDiagBuilder::K_Immediate;
1683 break;
1684 case FunctionEmissionStatus::TemplateDiscarded:
1685 case FunctionEmissionStatus::OMPDiscarded:
1686 Kind = DeviceDiagBuilder::K_Nop;
1687 break;
1688 case FunctionEmissionStatus::CUDADiscarded:
1689 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation")::llvm::llvm_unreachable_internal("CUDADiscarded unexpected in OpenMP device compilation"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1689)
;
1690 break;
1691 }
1692
1693 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1694}
1695
1696Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1697 unsigned DiagID) {
1698 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1699, __PRETTY_FUNCTION__))
1699 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1699, __PRETTY_FUNCTION__))
;
1700 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1701 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1702 switch (FES) {
1703 case FunctionEmissionStatus::Emitted:
1704 Kind = DeviceDiagBuilder::K_Immediate;
1705 break;
1706 case FunctionEmissionStatus::Unknown:
1707 Kind = DeviceDiagBuilder::K_Deferred;
1708 break;
1709 case FunctionEmissionStatus::TemplateDiscarded:
1710 case FunctionEmissionStatus::OMPDiscarded:
1711 case FunctionEmissionStatus::CUDADiscarded:
1712 Kind = DeviceDiagBuilder::K_Nop;
1713 break;
1714 }
1715
1716 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1717}
1718
1719void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
1720 bool CheckForDelayedContext) {
1721 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1722, __PRETTY_FUNCTION__))
1722 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1722, __PRETTY_FUNCTION__))
;
1723 assert(Callee && "Callee may not be null.")((Callee && "Callee may not be null.") ? static_cast<
void> (0) : __assert_fail ("Callee && \"Callee may not be null.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1723, __PRETTY_FUNCTION__))
;
1724 Callee = Callee->getMostRecentDecl();
1725 FunctionDecl *Caller = getCurFunctionDecl();
1726
1727 // host only function are not available on the device.
1728 if (Caller) {
1729 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1730 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1731 assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1733, __PRETTY_FUNCTION__))
1732 CalleeS != FunctionEmissionStatus::CUDADiscarded &&((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1733, __PRETTY_FUNCTION__))
1733 "CUDADiscarded unexpected in OpenMP device function check")((CallerS != FunctionEmissionStatus::CUDADiscarded &&
CalleeS != FunctionEmissionStatus::CUDADiscarded && "CUDADiscarded unexpected in OpenMP device function check"
) ? static_cast<void> (0) : __assert_fail ("CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded && \"CUDADiscarded unexpected in OpenMP device function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1733, __PRETTY_FUNCTION__))
;
1734 if ((CallerS == FunctionEmissionStatus::Emitted ||
1735 (!isOpenMPDeviceDelayedContext(*this) &&
1736 CallerS == FunctionEmissionStatus::Unknown)) &&
1737 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1738 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
1739 OMPC_device_type, OMPC_DEVICE_TYPE_host);
1740 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1741 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1742 diag::note_omp_marked_device_type_here)
1743 << HostDevTy;
1744 return;
1745 }
1746 }
1747 // If the caller is known-emitted, mark the callee as known-emitted.
1748 // Otherwise, mark the call in our call graph so we can traverse it later.
1749 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
1750 (!Caller && !CheckForDelayedContext) ||
1751 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1752 markKnownEmitted(*this, Caller, Callee, Loc,
1753 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
1754 return CheckForDelayedContext &&
1755 S.getEmissionStatus(FD) ==
1756 FunctionEmissionStatus::Emitted;
1757 });
1758 else if (Caller)
1759 DeviceCallGraph[Caller].insert({Callee, Loc});
1760}
1761
1762void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
1763 bool CheckCaller) {
1764 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1765, __PRETTY_FUNCTION__))
1765 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1765, __PRETTY_FUNCTION__))
;
1766 assert(Callee && "Callee may not be null.")((Callee && "Callee may not be null.") ? static_cast<
void> (0) : __assert_fail ("Callee && \"Callee may not be null.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1766, __PRETTY_FUNCTION__))
;
1767 Callee = Callee->getMostRecentDecl();
1768 FunctionDecl *Caller = getCurFunctionDecl();
1769
1770 // device only function are not available on the host.
1771 if (Caller) {
1772 FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1773 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1774 assert((((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1777, __PRETTY_FUNCTION__))
1775 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1777, __PRETTY_FUNCTION__))
1776 CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1777, __PRETTY_FUNCTION__))
1777 "CUDADiscarded unexpected in OpenMP host function check")(((LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded
&& CalleeS != FunctionEmissionStatus::CUDADiscarded)
) && "CUDADiscarded unexpected in OpenMP host function check"
) ? static_cast<void> (0) : __assert_fail ("(LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && CalleeS != FunctionEmissionStatus::CUDADiscarded)) && \"CUDADiscarded unexpected in OpenMP host function check\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1777, __PRETTY_FUNCTION__))
;
1778 if (CallerS == FunctionEmissionStatus::Emitted &&
1779 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1780 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
1781 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
1782 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1783 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1784 diag::note_omp_marked_device_type_here)
1785 << NoHostDevTy;
1786 return;
1787 }
1788 }
1789 // If the caller is known-emitted, mark the callee as known-emitted.
1790 // Otherwise, mark the call in our call graph so we can traverse it later.
1791 if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1792 if ((!CheckCaller && !Caller) ||
1793 (Caller &&
1794 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1795 markKnownEmitted(
1796 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) {
1797 return CheckCaller &&
1798 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted;
1799 });
1800 else if (Caller)
1801 DeviceCallGraph[Caller].insert({Callee, Loc});
1802 }
1803}
1804
1805void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1806 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice
&& "OpenMP device compilation mode is expected.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1807, __PRETTY_FUNCTION__))
1807 "OpenMP device compilation mode is expected.")((getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice
&& "OpenMP device compilation mode is expected.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && \"OpenMP device compilation mode is expected.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1807, __PRETTY_FUNCTION__))
;
1808 QualType Ty = E->getType();
1809 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1810 ((Ty->isFloat128Type() ||
1811 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
1812 !Context.getTargetInfo().hasFloat128Type()) ||
1813 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1814 !Context.getTargetInfo().hasInt128Type()))
1815 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type)
1816 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1817 << Context.getTargetInfo().getTriple().str() << E->getSourceRange();
1818}
1819
1820static OpenMPDefaultmapClauseKind
1821getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1822 if (LO.OpenMP <= 45) {
1823 if (VD->getType().getNonReferenceType()->isScalarType())
1824 return OMPC_DEFAULTMAP_scalar;
1825 return OMPC_DEFAULTMAP_aggregate;
1826 }
1827 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1828 return OMPC_DEFAULTMAP_pointer;
1829 if (VD->getType().getNonReferenceType()->isScalarType())
1830 return OMPC_DEFAULTMAP_scalar;
1831 return OMPC_DEFAULTMAP_aggregate;
1832}
1833
1834bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1835 unsigned OpenMPCaptureLevel) const {
1836 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1836, __PRETTY_FUNCTION__))
;
1837
1838 ASTContext &Ctx = getASTContext();
1839 bool IsByRef = true;
1840
1841 // Find the directive that is associated with the provided scope.
1842 D = cast<ValueDecl>(D->getCanonicalDecl());
1843 QualType Ty = D->getType();
1844
1845 bool IsVariableUsedInMapClause = false;
1846 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1847 // This table summarizes how a given variable should be passed to the device
1848 // given its type and the clauses where it appears. This table is based on
1849 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1850 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1851 //
1852 // =========================================================================
1853 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1854 // | |(tofrom:scalar)| | pvt | | | |
1855 // =========================================================================
1856 // | scl | | | | - | | bycopy|
1857 // | scl | | - | x | - | - | bycopy|
1858 // | scl | | x | - | - | - | null |
1859 // | scl | x | | | - | | byref |
1860 // | scl | x | - | x | - | - | bycopy|
1861 // | scl | x | x | - | - | - | null |
1862 // | scl | | - | - | - | x | byref |
1863 // | scl | x | - | - | - | x | byref |
1864 //
1865 // | agg | n.a. | | | - | | byref |
1866 // | agg | n.a. | - | x | - | - | byref |
1867 // | agg | n.a. | x | - | - | - | null |
1868 // | agg | n.a. | - | - | - | x | byref |
1869 // | agg | n.a. | - | - | - | x[] | byref |
1870 //
1871 // | ptr | n.a. | | | - | | bycopy|
1872 // | ptr | n.a. | - | x | - | - | bycopy|
1873 // | ptr | n.a. | x | - | - | - | null |
1874 // | ptr | n.a. | - | - | - | x | byref |
1875 // | ptr | n.a. | - | - | - | x[] | bycopy|
1876 // | ptr | n.a. | - | - | x | | bycopy|
1877 // | ptr | n.a. | - | - | x | x | bycopy|
1878 // | ptr | n.a. | - | - | x | x[] | bycopy|
1879 // =========================================================================
1880 // Legend:
1881 // scl - scalar
1882 // ptr - pointer
1883 // agg - aggregate
1884 // x - applies
1885 // - - invalid in this combination
1886 // [] - mapped with an array section
1887 // byref - should be mapped by reference
1888 // byval - should be mapped by value
1889 // null - initialize a local variable to null on the device
1890 //
1891 // Observations:
1892 // - All scalar declarations that show up in a map clause have to be passed
1893 // by reference, because they may have been mapped in the enclosing data
1894 // environment.
1895 // - If the scalar value does not fit the size of uintptr, it has to be
1896 // passed by reference, regardless the result in the table above.
1897 // - For pointers mapped by value that have either an implicit map or an
1898 // array section, the runtime library may pass the NULL value to the
1899 // device instead of the value passed to it by the compiler.
1900
1901 if (Ty->isReferenceType())
1902 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1903
1904 // Locate map clauses and see if the variable being captured is referred to
1905 // in any of those clauses. Here we only care about variables, not fields,
1906 // because fields are part of aggregates.
1907 bool IsVariableAssociatedWithSection = false;
1908
1909 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1910 D, Level,
1911 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1912 OMPClauseMappableExprCommon::MappableExprComponentListRef
1913 MapExprComponents,
1914 OpenMPClauseKind WhereFoundClauseKind) {
1915 // Only the map clause information influences how a variable is
1916 // captured. E.g. is_device_ptr does not require changing the default
1917 // behavior.
1918 if (WhereFoundClauseKind != OMPC_map)
1919 return false;
1920
1921 auto EI = MapExprComponents.rbegin();
1922 auto EE = MapExprComponents.rend();
1923
1924 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1924, __PRETTY_FUNCTION__))
;
1925
1926 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1927 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1928
1929 ++EI;
1930 if (EI == EE)
1931 return false;
1932
1933 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1934 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1935 isa<MemberExpr>(EI->getAssociatedExpression())) {
1936 IsVariableAssociatedWithSection = true;
1937 // There is nothing more we need to know about this variable.
1938 return true;
1939 }
1940
1941 // Keep looking for more map info.
1942 return false;
1943 });
1944
1945 if (IsVariableUsedInMapClause) {
1946 // If variable is identified in a map clause it is always captured by
1947 // reference except if it is a pointer that is dereferenced somehow.
1948 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1949 } else {
1950 // By default, all the data that has a scalar type is mapped by copy
1951 // (except for reduction variables).
1952 // Defaultmap scalar is mutual exclusive to defaultmap pointer
1953 IsByRef =
1954 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable() &&
1955 !Ty->isAnyPointerType()) ||
1956 !Ty->isScalarType() ||
1957 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isDefaultmapCapturedByRef(
1958 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
1959 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1960 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1961 }
1962 }
1963
1964 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1965 IsByRef =
1966 ((IsVariableUsedInMapClause &&
1967 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1968 OMPD_target) ||
1969 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1970 D,
1971 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1972 Level, /*NotLastprivate=*/true)) &&
1973 // If the variable is artificial and must be captured by value - try to
1974 // capture by value.
1975 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1976 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1977 }
1978
1979 // When passing data by copy, we need to make sure it fits the uintptr size
1980 // and alignment, because the runtime library only deals with uintptr types.
1981 // If it does not fit the uintptr size, we need to pass the data by reference
1982 // instead.
1983 if (!IsByRef &&
1984 (Ctx.getTypeSizeInChars(Ty) >
1985 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1986 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1987 IsByRef = true;
1988 }
1989
1990 return IsByRef;
1991}
1992
1993unsigned Sema::getOpenMPNestingLevel() const {
1994 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 1994, __PRETTY_FUNCTION__))
;
1995 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
1996}
1997
1998bool Sema::isInOpenMPTargetExecutionDirective() const {
1999 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2000 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
2001 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
2002 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2003 SourceLocation) -> bool {
2004 return isOpenMPTargetExecutionDirective(K);
2005 },
2006 false);
2007}
2008
2009VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2010 unsigned StopAt) {
2011 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2011, __PRETTY_FUNCTION__))
;
2012 D = getCanonicalDecl(D);
2013
2014 auto *VD = dyn_cast<VarDecl>(D);
2015 // Do not capture constexpr variables.
2016 if (VD && VD->isConstexpr())
2017 return nullptr;
2018
2019 // If we want to determine whether the variable should be captured from the
2020 // perspective of the current capturing scope, and we've already left all the
2021 // capturing scopes of the top directive on the stack, check from the
2022 // perspective of its parent directive (if any) instead.
2023 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2024 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, CheckScopeInfo && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isBodyComplete());
2025
2026 // If we are attempting to capture a global variable in a directive with
2027 // 'target' we return true so that this global is also mapped to the device.
2028 //
2029 if (VD && !VD->hasLocalStorage() &&
2030 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2031 if (isInOpenMPDeclareTargetContext()) {
2032 // Try to mark variable as declare target if it is used in capturing
2033 // regions.
2034 if (LangOpts.OpenMP <= 45 &&
2035 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2036 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2037 return nullptr;
2038 } else if (isInOpenMPTargetExecutionDirective()) {
2039 // If the declaration is enclosed in a 'declare target' directive,
2040 // then it should not be captured.
2041 //
2042 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2043 return nullptr;
2044 CapturedRegionScopeInfo *CSI = nullptr;
2045 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2046 llvm::reverse(FunctionScopes),
2047 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2048 if (!isa<CapturingScopeInfo>(FSI))
2049 return nullptr;
2050 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2051 if (RSI->CapRegionKind == CR_OpenMP) {
2052 CSI = RSI;
2053 break;
2054 }
2055 }
2056 SmallVector<OpenMPDirectiveKind, 4> Regions;
2057 getOpenMPCaptureRegions(Regions,
2058 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(CSI->OpenMPLevel));
2059 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2060 return VD;
2061 }
2062 }
2063
2064 if (CheckScopeInfo) {
2065 bool OpenMPFound = false;
2066 for (unsigned I = StopAt + 1; I > 0; --I) {
2067 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2068 if(!isa<CapturingScopeInfo>(FSI))
2069 return nullptr;
2070 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2071 if (RSI->CapRegionKind == CR_OpenMP) {
2072 OpenMPFound = true;
2073 break;
2074 }
2075 }
2076 if (!OpenMPFound)
2077 return nullptr;
2078 }
2079
2080 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
2081 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
2082 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
2083 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
2084 if (Info.first ||
2085 (VD && VD->hasLocalStorage() &&
2086 isImplicitOrExplicitTaskingRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
2087 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
2088 return VD ? VD : Info.second;
2089 DSAStackTy::DSAVarData DVarPrivate =
2090 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2091 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
2092 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2093 // Threadprivate variables must not be captured.
2094 if (isOpenMPThreadPrivate(DVarPrivate.CKind))
2095 return nullptr;
2096 // The variable is not private or it is the variable in the directive with
2097 // default(none) clause and not used in any clause.
2098 DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(D, isOpenMPPrivate,
2099 [](OpenMPDirectiveKind) { return true; },
2100 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
2101 if (DVarPrivate.CKind != OMPC_unknown ||
2102 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none))
2103 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2104 }
2105 return nullptr;
2106}
2107
2108void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2109 unsigned Level) const {
2110 SmallVector<OpenMPDirectiveKind, 4> Regions;
2111 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2112 FunctionScopesIndex -= Regions.size();
2113}
2114
2115void Sema::startOpenMPLoop() {
2116 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2116, __PRETTY_FUNCTION__))
;
2117 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2118 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopInit();
2119}
2120
2121void Sema::startOpenMPCXXRangeFor() {
2122 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2122, __PRETTY_FUNCTION__))
;
2123 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2124 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
2125 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2126 }
2127}
2128
2129bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
2130 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2130, __PRETTY_FUNCTION__))
;
2131 if (isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
2132 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() > 0 &&
2133 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopStarted()) {
2134 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter(D);
2135 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
2136 return true;
2137 }
2138 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2139 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D).first) &&
2140 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2141 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2142 !isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))
2143 return true;
2144 }
2145 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2146 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2147 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing() &&
2148 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2149 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2150 return true;
2151 }
2152 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
2153 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2154 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
2155 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
2156 // Consider taskgroup reduction descriptor variable a private to avoid
2157 // possible capture in the region.
2158 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
2159 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
2160 Level) &&
2161 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level));
2162}
2163
2164void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2165 unsigned Level) {
2166 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2166, __PRETTY_FUNCTION__))
;
2167 D = getCanonicalDecl(D);
2168 OpenMPClauseKind OMPC = OMPC_unknown;
2169 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
2170 const unsigned NewLevel = I - 1;
2171 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
2172 [&OMPC](const OpenMPClauseKind K) {
2173 if (isOpenMPPrivate(K)) {
2174 OMPC = K;
2175 return true;
2176 }
2177 return false;
2178 },
2179 NewLevel))
2180 break;
2181 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
2182 D, NewLevel,
2183 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2184 OpenMPClauseKind) { return true; })) {
2185 OMPC = OMPC_map;
2186 break;
2187 }
2188 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2189 NewLevel)) {
2190 OMPC = OMPC_map;
2191 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->mustBeFirstprivateAtLevel(
2192 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2193 OMPC = OMPC_firstprivate;
2194 break;
2195 }
2196 }
2197 if (OMPC != OMPC_unknown)
2198 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2199}
2200
2201bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2202 unsigned CaptureLevel) const {
2203 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2203, __PRETTY_FUNCTION__))
;
2204 // Return true if the current level is no longer enclosed in a target region.
2205
2206 SmallVector<OpenMPDirectiveKind, 4> Regions;
2207 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
2208 const auto *VD = dyn_cast<VarDecl>(D);
2209 return VD && !VD->hasLocalStorage() &&
2210 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2211 Level) &&
2212 Regions[CaptureLevel] != OMPD_task;
2213}
2214
2215void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
2216
2217void Sema::finalizeOpenMPDelayedAnalysis() {
2218 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2218, __PRETTY_FUNCTION__))
;
2219 // Diagnose implicit declare target functions and their callees.
2220 for (const auto &CallerCallees : DeviceCallGraph) {
2221 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2222 OMPDeclareTargetDeclAttr::getDeviceType(
2223 CallerCallees.getFirst()->getMostRecentDecl());
2224 // Ignore host functions during device analyzis.
2225 if (LangOpts.OpenMPIsDevice && DevTy &&
2226 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2227 continue;
2228 // Ignore nohost functions during host analyzis.
2229 if (!LangOpts.OpenMPIsDevice && DevTy &&
2230 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2231 continue;
2232 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation>
2233 &Callee : CallerCallees.getSecond()) {
2234 const FunctionDecl *FD = Callee.first->getMostRecentDecl();
2235 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2236 OMPDeclareTargetDeclAttr::getDeviceType(FD);
2237 if (LangOpts.OpenMPIsDevice && DevTy &&
2238 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2239 // Diagnose host function called during device codegen.
2240 StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
2241 OMPC_device_type, OMPC_DEVICE_TYPE_host);
2242 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2243 << HostDevTy << 0;
2244 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2245 diag::note_omp_marked_device_type_here)
2246 << HostDevTy;
2247 continue;
2248 }
2249 if (!LangOpts.OpenMPIsDevice && DevTy &&
2250 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2251 // Diagnose nohost function called during host codegen.
2252 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2253 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2254 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2255 << NoHostDevTy << 1;
2256 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2257 diag::note_omp_marked_device_type_here)
2258 << NoHostDevTy;
2259 continue;
2260 }
2261 }
2262 }
2263}
2264
2265void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2266 const DeclarationNameInfo &DirName,
2267 Scope *CurScope, SourceLocation Loc) {
2268 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
2269 PushExpressionEvaluationContext(
2270 ExpressionEvaluationContext::PotentiallyEvaluated);
2271}
2272
2273void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2274 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
2275}
2276
2277void Sema::EndOpenMPClause() {
2278 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
2279}
2280
2281static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2282 ArrayRef<OMPClause *> Clauses);
2283static std::pair<ValueDecl *, bool>
2284getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2285 SourceRange &ERange, bool AllowArraySection = false);
2286static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2287 bool WithInit);
2288
2289void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2290 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2291 // A variable of class type (or array thereof) that appears in a lastprivate
2292 // clause requires an accessible, unambiguous default constructor for the
2293 // class type, unless the list item is also specified in a firstprivate
2294 // clause.
2295 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2296 for (OMPClause *C : D->clauses()) {
2297 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2298 SmallVector<Expr *, 8> PrivateCopies;
2299 for (Expr *DE : Clause->varlists()) {
2300 if (DE->isValueDependent() || DE->isTypeDependent()) {
2301 PrivateCopies.push_back(nullptr);
2302 continue;
2303 }
2304 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2305 auto *VD = cast<VarDecl>(DRE->getDecl());
2306 QualType Type = VD->getType().getNonReferenceType();
2307 const DSAStackTy::DSAVarData DVar =
2308 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
2309 if (DVar.CKind == OMPC_lastprivate) {
2310 // Generate helper private variable and initialize it with the
2311 // default value. The address of the original variable is replaced
2312 // by the address of the new private variable in CodeGen. This new
2313 // variable is not added to IdResolver, so the code in the OpenMP
2314 // region uses original variable for proper diagnostics.
2315 VarDecl *VDPrivate = buildVarDecl(
2316 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2317 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2318 ActOnUninitializedDecl(VDPrivate);
2319 if (VDPrivate->isInvalidDecl()) {
2320 PrivateCopies.push_back(nullptr);
2321 continue;
2322 }
2323 PrivateCopies.push_back(buildDeclRefExpr(
2324 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2325 } else {
2326 // The variable is also a firstprivate, so initialization sequence
2327 // for private copy is generated already.
2328 PrivateCopies.push_back(nullptr);
2329 }
2330 }
2331 Clause->setPrivateCopies(PrivateCopies);
2332 continue;
2333 }
2334 // Finalize nontemporal clause by handling private copies, if any.
2335 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2336 SmallVector<Expr *, 8> PrivateRefs;
2337 for (Expr *RefExpr : Clause->varlists()) {
2338 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2338, __PRETTY_FUNCTION__))
;
2339 SourceLocation ELoc;
2340 SourceRange ERange;
2341 Expr *SimpleRefExpr = RefExpr;
2342 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2343 if (Res.second)
2344 // It will be analyzed later.
2345 PrivateRefs.push_back(RefExpr);
2346 ValueDecl *D = Res.first;
2347 if (!D)
2348 continue;
2349
2350 const DSAStackTy::DSAVarData DVar =
2351 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
2352 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2353 : SimpleRefExpr);
2354 }
2355 Clause->setPrivateRefs(PrivateRefs);
2356 continue;
2357 }
2358 }
2359 // Check allocate clauses.
2360 if (!CurContext->isDependentContext())
2361 checkAllocateClauses(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D->clauses());
2362 }
2363
2364 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
2365 DiscardCleanupsInEvaluationContext();
2366 PopExpressionEvaluationContext();
2367}
2368
2369static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2370 Expr *NumIterations, Sema &SemaRef,
2371 Scope *S, DSAStackTy *Stack);
2372
2373namespace {
2374
2375class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2376private:
2377 Sema &SemaRef;
2378
2379public:
2380 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2381 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2382 NamedDecl *ND = Candidate.getCorrectionDecl();
2383 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2384 return VD->hasGlobalStorage() &&
2385 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2386 SemaRef.getCurScope());
2387 }
2388 return false;
2389 }
2390
2391 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2392 return std::make_unique<VarDeclFilterCCC>(*this);
2393 }
2394
2395};
2396
2397class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2398private:
2399 Sema &SemaRef;
2400
2401public:
2402 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2403 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2404 NamedDecl *ND = Candidate.getCorrectionDecl();
2405 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2406 isa<FunctionDecl>(ND))) {
2407 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2408 SemaRef.getCurScope());
2409 }
2410 return false;
2411 }
2412
2413 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2414 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2415 }
2416};
2417
2418} // namespace
2419
2420ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2421 CXXScopeSpec &ScopeSpec,
2422 const DeclarationNameInfo &Id,
2423 OpenMPDirectiveKind Kind) {
2424 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2425 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2426
2427 if (Lookup.isAmbiguous())
2428 return ExprError();
2429
2430 VarDecl *VD;
2431 if (!Lookup.isSingleResult()) {
2432 VarDeclFilterCCC CCC(*this);
2433 if (TypoCorrection Corrected =
2434 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2435 CTK_ErrorRecovery)) {
2436 diagnoseTypo(Corrected,
2437 PDiag(Lookup.empty()
2438 ? diag::err_undeclared_var_use_suggest
2439 : diag::err_omp_expected_var_arg_suggest)
2440 << Id.getName());
2441 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2442 } else {
2443 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2444 : diag::err_omp_expected_var_arg)
2445 << Id.getName();
2446 return ExprError();
2447 }
2448 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2449 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2450 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2451 return ExprError();
2452 }
2453 Lookup.suppressDiagnostics();
2454
2455 // OpenMP [2.9.2, Syntax, C/C++]
2456 // Variables must be file-scope, namespace-scope, or static block-scope.
2457 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2458 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2459 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2460 bool IsDecl =
2461 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2462 Diag(VD->getLocation(),
2463 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2464 << VD;
2465 return ExprError();
2466 }
2467
2468 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2469 NamedDecl *ND = CanonicalVD;
2470 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2471 // A threadprivate directive for file-scope variables must appear outside
2472 // any definition or declaration.
2473 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2474 !getCurLexicalContext()->isTranslationUnit()) {
2475 Diag(Id.getLoc(), diag::err_omp_var_scope)
2476 << getOpenMPDirectiveName(Kind) << VD;
2477 bool IsDecl =
2478 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2479 Diag(VD->getLocation(),
2480 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2481 << VD;
2482 return ExprError();
2483 }
2484 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2485 // A threadprivate directive for static class member variables must appear
2486 // in the class definition, in the same scope in which the member
2487 // variables are declared.
2488 if (CanonicalVD->isStaticDataMember() &&
2489 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2490 Diag(Id.getLoc(), diag::err_omp_var_scope)
2491 << getOpenMPDirectiveName(Kind) << VD;
2492 bool IsDecl =
2493 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2494 Diag(VD->getLocation(),
2495 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2496 << VD;
2497 return ExprError();
2498 }
2499 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2500 // A threadprivate directive for namespace-scope variables must appear
2501 // outside any definition or declaration other than the namespace
2502 // definition itself.
2503 if (CanonicalVD->getDeclContext()->isNamespace() &&
2504 (!getCurLexicalContext()->isFileContext() ||
2505 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2506 Diag(Id.getLoc(), diag::err_omp_var_scope)
2507 << getOpenMPDirectiveName(Kind) << VD;
2508 bool IsDecl =
2509 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2510 Diag(VD->getLocation(),
2511 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2512 << VD;
2513 return ExprError();
2514 }
2515 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2516 // A threadprivate directive for static block-scope variables must appear
2517 // in the scope of the variable and not in a nested scope.
2518 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2519 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2520 Diag(Id.getLoc(), diag::err_omp_var_scope)
2521 << getOpenMPDirectiveName(Kind) << VD;
2522 bool IsDecl =
2523 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2524 Diag(VD->getLocation(),
2525 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2526 << VD;
2527 return ExprError();
2528 }
2529
2530 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2531 // A threadprivate directive must lexically precede all references to any
2532 // of the variables in its list.
2533 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2534 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
2535 Diag(Id.getLoc(), diag::err_omp_var_used)
2536 << getOpenMPDirectiveName(Kind) << VD;
2537 return ExprError();
2538 }
2539
2540 QualType ExprType = VD->getType().getNonReferenceType();
2541 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2542 SourceLocation(), VD,
2543 /*RefersToEnclosingVariableOrCapture=*/false,
2544 Id.getLoc(), ExprType, VK_LValue);
2545}
2546
2547Sema::DeclGroupPtrTy
2548Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2549 ArrayRef<Expr *> VarList) {
2550 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2551 CurContext->addDecl(D);
2552 return DeclGroupPtrTy::make(DeclGroupRef(D));
2553 }
2554 return nullptr;
2555}
2556
2557namespace {
2558class LocalVarRefChecker final
2559 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2560 Sema &SemaRef;
2561
2562public:
2563 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2564 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2565 if (VD->hasLocalStorage()) {
2566 SemaRef.Diag(E->getBeginLoc(),
2567 diag::err_omp_local_var_in_threadprivate_init)
2568 << E->getSourceRange();
2569 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2570 << VD << VD->getSourceRange();
2571 return true;
2572 }
2573 }
2574 return false;
2575 }
2576 bool VisitStmt(const Stmt *S) {
2577 for (const Stmt *Child : S->children()) {
2578 if (Child && Visit(Child))
2579 return true;
2580 }
2581 return false;
2582 }
2583 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2584};
2585} // namespace
2586
2587OMPThreadPrivateDecl *
2588Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2589 SmallVector<Expr *, 8> Vars;
2590 for (Expr *RefExpr : VarList) {
2591 auto *DE = cast<DeclRefExpr>(RefExpr);
2592 auto *VD = cast<VarDecl>(DE->getDecl());
2593 SourceLocation ILoc = DE->getExprLoc();
2594
2595 // Mark variable as used.
2596 VD->setReferenced();
2597 VD->markUsed(Context);
2598
2599 QualType QType = VD->getType();
2600 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2601 // It will be analyzed later.
2602 Vars.push_back(DE);
2603 continue;
2604 }
2605
2606 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2607 // A threadprivate variable must not have an incomplete type.
2608 if (RequireCompleteType(ILoc, VD->getType(),
2609 diag::err_omp_threadprivate_incomplete_type)) {
2610 continue;
2611 }
2612
2613 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2614 // A threadprivate variable must not have a reference type.
2615 if (VD->getType()->isReferenceType()) {
2616 Diag(ILoc, diag::err_omp_ref_type_arg)
2617 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2618 bool IsDecl =
2619 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2620 Diag(VD->getLocation(),
2621 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2622 << VD;
2623 continue;
2624 }
2625
2626 // Check if this is a TLS variable. If TLS is not being supported, produce
2627 // the corresponding diagnostic.
2628 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2629 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2630 getLangOpts().OpenMPUseTLS &&
2631 getASTContext().getTargetInfo().isTLSSupported())) ||
2632 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2633 !VD->isLocalVarDecl())) {
2634 Diag(ILoc, diag::err_omp_var_thread_local)
2635 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2636 bool IsDecl =
2637 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2638 Diag(VD->getLocation(),
2639 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2640 << VD;
2641 continue;
2642 }
2643
2644 // Check if initial value of threadprivate variable reference variable with
2645 // local storage (it is not supported by runtime).
2646 if (const Expr *Init = VD->getAnyInitializer()) {
2647 LocalVarRefChecker Checker(*this);
2648 if (Checker.Visit(Init))
2649 continue;
2650 }
2651
2652 Vars.push_back(RefExpr);
2653 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
2654 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2655 Context, SourceRange(Loc, Loc)));
2656 if (ASTMutationListener *ML = Context.getASTMutationListener())
2657 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2658 }
2659 OMPThreadPrivateDecl *D = nullptr;
2660 if (!Vars.empty()) {
2661 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2662 Vars);
2663 D->setAccess(AS_public);
2664 }
2665 return D;
2666}
2667
2668static OMPAllocateDeclAttr::AllocatorTypeTy
2669getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2670 if (!Allocator)
2671 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2672 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2673 Allocator->isInstantiationDependent() ||
2674 Allocator->containsUnexpandedParameterPack())
2675 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2676 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2677 const Expr *AE = Allocator->IgnoreParenImpCasts();
2678 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2679 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2680 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2681 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2682 llvm::FoldingSetNodeID AEId, DAEId;
2683 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2684 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2685 if (AEId == DAEId) {
2686 AllocatorKindRes = AllocatorKind;
2687 break;
2688 }
2689 }
2690 return AllocatorKindRes;
2691}
2692
2693static bool checkPreviousOMPAllocateAttribute(
2694 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2695 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2696 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2697 return false;
2698 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2699 Expr *PrevAllocator = A->getAllocator();
2700 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2701 getAllocatorKind(S, Stack, PrevAllocator);
2702 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2703 if (AllocatorsMatch &&
2704 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2705 Allocator && PrevAllocator) {
2706 const Expr *AE = Allocator->IgnoreParenImpCasts();
2707 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2708 llvm::FoldingSetNodeID AEId, PAEId;
2709 AE->Profile(AEId, S.Context, /*Canonical=*/true);
2710 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2711 AllocatorsMatch = AEId == PAEId;
2712 }
2713 if (!AllocatorsMatch) {
2714 SmallString<256> AllocatorBuffer;
2715 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2716 if (Allocator)
2717 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2718 SmallString<256> PrevAllocatorBuffer;
2719 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2720 if (PrevAllocator)
2721 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2722 S.getPrintingPolicy());
2723
2724 SourceLocation AllocatorLoc =
2725 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2726 SourceRange AllocatorRange =
2727 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2728 SourceLocation PrevAllocatorLoc =
2729 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2730 SourceRange PrevAllocatorRange =
2731 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2732 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2733 << (Allocator ? 1 : 0) << AllocatorStream.str()
2734 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2735 << AllocatorRange;
2736 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2737 << PrevAllocatorRange;
2738 return true;
2739 }
2740 return false;
2741}
2742
2743static void
2744applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
2745 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2746 Expr *Allocator, SourceRange SR) {
2747 if (VD->hasAttr<OMPAllocateDeclAttr>())
2748 return;
2749 if (Allocator &&
2750 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2751 Allocator->isInstantiationDependent() ||
2752 Allocator->containsUnexpandedParameterPack()))
2753 return;
2754 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2755 Allocator, SR);
2756 VD->addAttr(A);
2757 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
2758 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2759}
2760
2761Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
2762 SourceLocation Loc, ArrayRef<Expr *> VarList,
2763 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2764 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2764, __PRETTY_FUNCTION__))
;
2765 Expr *Allocator = nullptr;
2766 if (Clauses.empty()) {
2767 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2768 // allocate directives that appear in a target region must specify an
2769 // allocator clause unless a requires directive with the dynamic_allocators
2770 // clause is present in the same compilation unit.
2771 if (LangOpts.OpenMPIsDevice &&
2772 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
2773 targetDiag(Loc, diag::err_expected_allocator_clause);
2774 } else {
2775 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2776 }
2777 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2778 getAllocatorKind(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Allocator);
2779 SmallVector<Expr *, 8> Vars;
2780 for (Expr *RefExpr : VarList) {
2781 auto *DE = cast<DeclRefExpr>(RefExpr);
2782 auto *VD = cast<VarDecl>(DE->getDecl());
2783
2784 // Check if this is a TLS variable or global register.
2785 if (VD->getTLSKind() != VarDecl::TLS_None ||
2786 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2787 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2788 !VD->isLocalVarDecl()))
2789 continue;
2790
2791 // If the used several times in the allocate directive, the same allocator
2792 // must be used.
2793 if (checkPreviousOMPAllocateAttribute(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, RefExpr, VD,
2794 AllocatorKind, Allocator))
2795 continue;
2796
2797 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2798 // If a list item has a static storage type, the allocator expression in the
2799 // allocator clause must be a constant expression that evaluates to one of
2800 // the predefined memory allocator values.
2801 if (Allocator && VD->hasGlobalStorage()) {
2802 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2803 Diag(Allocator->getExprLoc(),
2804 diag::err_omp_expected_predefined_allocator)
2805 << Allocator->getSourceRange();
2806 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2807 VarDecl::DeclarationOnly;
2808 Diag(VD->getLocation(),
2809 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2810 << VD;
2811 continue;
2812 }
2813 }
2814
2815 Vars.push_back(RefExpr);
2816 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2817 DE->getSourceRange());
2818 }
2819 if (Vars.empty())
2820 return nullptr;
2821 if (!Owner)
2822 Owner = getCurLexicalContext();
2823 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
2824 D->setAccess(AS_public);
2825 Owner->addDecl(D);
2826 return DeclGroupPtrTy::make(DeclGroupRef(D));
2827}
2828
2829Sema::DeclGroupPtrTy
2830Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
2831 ArrayRef<OMPClause *> ClauseList) {
2832 OMPRequiresDecl *D = nullptr;
2833 if (!CurContext->isFileContext()) {
2834 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2835 } else {
2836 D = CheckOMPRequiresDecl(Loc, ClauseList);
2837 if (D) {
2838 CurContext->addDecl(D);
2839 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
2840 }
2841 }
2842 return DeclGroupPtrTy::make(DeclGroupRef(D));
2843}
2844
2845OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
2846 ArrayRef<OMPClause *> ClauseList) {
2847 /// For target specific clauses, the requires directive cannot be
2848 /// specified after the handling of any of the target regions in the
2849 /// current compilation unit.
2850 ArrayRef<SourceLocation> TargetLocations =
2851 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getEncounteredTargetLocs();
2852 SourceLocation AtomicLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAtomicDirectiveLoc();
2853 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
2854 for (const OMPClause *CNew : ClauseList) {
2855 // Check if any of the requires clauses affect target regions.
2856 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2857 isa<OMPUnifiedAddressClause>(CNew) ||
2858 isa<OMPReverseOffloadClause>(CNew) ||
2859 isa<OMPDynamicAllocatorsClause>(CNew)) {
2860 Diag(Loc, diag::err_omp_directive_before_requires)
2861 << "target" << getOpenMPClauseName(CNew->getClauseKind());
2862 for (SourceLocation TargetLoc : TargetLocations) {
2863 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
2864 << "target";
2865 }
2866 } else if (!AtomicLoc.isInvalid() &&
2867 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
2868 Diag(Loc, diag::err_omp_directive_before_requires)
2869 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
2870 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
2871 << "atomic";
2872 }
2873 }
2874 }
2875
2876 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
2877 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2878 ClauseList);
2879 return nullptr;
2880}
2881
2882static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2883 const ValueDecl *D,
2884 const DSAStackTy::DSAVarData &DVar,
2885 bool IsLoopIterVar = false) {
2886 if (DVar.RefExpr) {
2887 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2888 << getOpenMPClauseName(DVar.CKind);
2889 return;
2890 }
2891 enum {
2892 PDSA_StaticMemberShared,
2893 PDSA_StaticLocalVarShared,
2894 PDSA_LoopIterVarPrivate,
2895 PDSA_LoopIterVarLinear,
2896 PDSA_LoopIterVarLastprivate,
2897 PDSA_ConstVarShared,
2898 PDSA_GlobalVarShared,
2899 PDSA_TaskVarFirstprivate,
2900 PDSA_LocalVarPrivate,
2901 PDSA_Implicit
2902 } Reason = PDSA_Implicit;
2903 bool ReportHint = false;
2904 auto ReportLoc = D->getLocation();
2905 auto *VD = dyn_cast<VarDecl>(D);
2906 if (IsLoopIterVar) {
2907 if (DVar.CKind == OMPC_private)
2908 Reason = PDSA_LoopIterVarPrivate;
2909 else if (DVar.CKind == OMPC_lastprivate)
2910 Reason = PDSA_LoopIterVarLastprivate;
2911 else
2912 Reason = PDSA_LoopIterVarLinear;
2913 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2914 DVar.CKind == OMPC_firstprivate) {
2915 Reason = PDSA_TaskVarFirstprivate;
2916 ReportLoc = DVar.ImplicitDSALoc;
2917 } else if (VD && VD->isStaticLocal())
2918 Reason = PDSA_StaticLocalVarShared;
2919 else if (VD && VD->isStaticDataMember())
2920 Reason = PDSA_StaticMemberShared;
2921 else if (VD && VD->isFileVarDecl())
2922 Reason = PDSA_GlobalVarShared;
2923 else if (D->getType().isConstant(SemaRef.getASTContext()))
2924 Reason = PDSA_ConstVarShared;
2925 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2926 ReportHint = true;
2927 Reason = PDSA_LocalVarPrivate;
2928 }
2929 if (Reason != PDSA_Implicit) {
2930 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2931 << Reason << ReportHint
2932 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2933 } else if (DVar.ImplicitDSALoc.isValid()) {
2934 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2935 << getOpenMPClauseName(DVar.CKind);
2936 }
2937}
2938
2939static OpenMPMapClauseKind
2940getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
2941 bool IsAggregateOrDeclareTarget) {
2942 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
2943 switch (M) {
2944 case OMPC_DEFAULTMAP_MODIFIER_alloc:
2945 Kind = OMPC_MAP_alloc;
2946 break;
2947 case OMPC_DEFAULTMAP_MODIFIER_to:
2948 Kind = OMPC_MAP_to;
2949 break;
2950 case OMPC_DEFAULTMAP_MODIFIER_from:
2951 Kind = OMPC_MAP_from;
2952 break;
2953 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
2954 Kind = OMPC_MAP_tofrom;
2955 break;
2956 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
2957 case OMPC_DEFAULTMAP_MODIFIER_last:
2958 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2958)
;
2959 case OMPC_DEFAULTMAP_MODIFIER_none:
2960 case OMPC_DEFAULTMAP_MODIFIER_default:
2961 case OMPC_DEFAULTMAP_MODIFIER_unknown:
2962 // IsAggregateOrDeclareTarget could be true if:
2963 // 1. the implicit behavior for aggregate is tofrom
2964 // 2. it's a declare target link
2965 if (IsAggregateOrDeclareTarget) {
2966 Kind = OMPC_MAP_tofrom;
2967 break;
2968 }
2969 llvm_unreachable("Unexpected defaultmap implicit behavior")::llvm::llvm_unreachable_internal("Unexpected defaultmap implicit behavior"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2969)
;
2970 }
2971 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 2971, __PRETTY_FUNCTION__))
;
2972 return Kind;
2973}
2974
2975namespace {
2976class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2977 DSAStackTy *Stack;
2978 Sema &SemaRef;
2979 bool ErrorFound = false;
2980 bool TryCaptureCXXThisMembers = false;
2981 CapturedStmt *CS = nullptr;
2982 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2983 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
2984 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2985 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2986
2987 void VisitSubCaptures(OMPExecutableDirective *S) {
2988 // Check implicitly captured variables.
2989 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2990 return;
2991 visitSubCaptures(S->getInnermostCapturedStmt());
2992 // Try to capture inner this->member references to generate correct mappings
2993 // and diagnostics.
2994 if (TryCaptureCXXThisMembers ||
2995 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2996 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
2997 [](const CapturedStmt::Capture &C) {
2998 return C.capturesThis();
2999 }))) {
3000 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3001 TryCaptureCXXThisMembers = true;
3002 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3003 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3004 }
3005 }
3006
3007public:
3008 void VisitDeclRefExpr(DeclRefExpr *E) {
3009 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3010 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3011 E->isInstantiationDependent())
3012 return;
3013 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3014 // Check the datasharing rules for the expressions in the clauses.
3015 if (!CS) {
3016 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3017 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3018 Visit(CED->getInit());
3019 return;
3020 }
3021 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3022 // Do not analyze internal variables and do not enclose them into
3023 // implicit clauses.
3024 return;
3025 VD = VD->getCanonicalDecl();
3026 // Skip internally declared variables.
3027 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
3028 return;
3029
3030 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3031 // Check if the variable has explicit DSA set and stop analysis if it so.
3032 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3033 return;
3034
3035 // Skip internally declared static variables.
3036 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3037 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3038 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3039 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3040 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
3041 return;
3042
3043 SourceLocation ELoc = E->getExprLoc();
3044 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3045 // The default(none) clause requires that each variable that is referenced
3046 // in the construct, and does not have a predetermined data-sharing
3047 // attribute, must have its data-sharing attribute explicitly determined
3048 // by being listed in a data-sharing attribute clause.
3049 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
3050 isImplicitOrExplicitTaskingRegion(DKind) &&
3051 VarsWithInheritedDSA.count(VD) == 0) {
3052 VarsWithInheritedDSA[VD] = E;
3053 return;
3054 }
3055
3056 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3057 // If implicit-behavior is none, each variable referenced in the
3058 // construct that does not have a predetermined data-sharing attribute
3059 // and does not appear in a to or link clause on a declare target
3060 // directive must be listed in a data-mapping attribute clause, a
3061 // data-haring attribute clause (including a data-sharing attribute
3062 // clause on a combined construct where target. is one of the
3063 // constituent constructs), or an is_device_ptr clause.
3064 OpenMPDefaultmapClauseKind ClauseKind =
3065 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3066 if (SemaRef.getLangOpts().OpenMP >= 50) {
3067 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3068 OMPC_DEFAULTMAP_MODIFIER_none;
3069 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3070 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3071 // Only check for data-mapping attribute and is_device_ptr here
3072 // since we have already make sure that the declaration does not
3073 // have a data-sharing attribute above
3074 if (!Stack->checkMappableExprComponentListsForDecl(
3075 VD, /*CurrentRegionOnly=*/true,
3076 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3077 MapExprComponents,
3078 OpenMPClauseKind) {
3079 auto MI = MapExprComponents.rbegin();
3080 auto ME = MapExprComponents.rend();
3081 return MI != ME && MI->getAssociatedDeclaration() == VD;
3082 })) {
3083 VarsWithInheritedDSA[VD] = E;
3084 return;
3085 }
3086 }
3087 }
3088
3089 if (isOpenMPTargetExecutionDirective(DKind) &&
3090 !Stack->isLoopControlVariable(VD).first) {
3091 if (!Stack->checkMappableExprComponentListsForDecl(
3092 VD, /*CurrentRegionOnly=*/true,
3093 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3094 StackComponents,
3095 OpenMPClauseKind) {
3096 // Variable is used if it has been marked as an array, array
3097 // section or the variable iself.
3098 return StackComponents.size() == 1 ||
3099 std::all_of(
3100 std::next(StackComponents.rbegin()),
3101 StackComponents.rend(),
3102 [](const OMPClauseMappableExprCommon::
3103 MappableComponent &MC) {
3104 return MC.getAssociatedDeclaration() ==
3105 nullptr &&
3106 (isa<OMPArraySectionExpr>(
3107 MC.getAssociatedExpression()) ||
3108 isa<ArraySubscriptExpr>(
3109 MC.getAssociatedExpression()));
3110 });
3111 })) {
3112 bool IsFirstprivate = false;
3113 // By default lambdas are captured as firstprivates.
3114 if (const auto *RD =
3115 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3116 IsFirstprivate = RD->isLambda();
3117 IsFirstprivate =
3118 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3119 if (IsFirstprivate) {
3120 ImplicitFirstprivate.emplace_back(E);
3121 } else {
3122 OpenMPDefaultmapClauseModifier M =
3123 Stack->getDefaultmapModifier(ClauseKind);
3124 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3125 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3126 ImplicitMap[Kind].emplace_back(E);
3127 }
3128 return;
3129 }
3130 }
3131
3132 // OpenMP [2.9.3.6, Restrictions, p.2]
3133 // A list item that appears in a reduction clause of the innermost
3134 // enclosing worksharing or parallel construct may not be accessed in an
3135 // explicit task.
3136 DVar = Stack->hasInnermostDSA(
3137 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3138 [](OpenMPDirectiveKind K) {
3139 return isOpenMPParallelDirective(K) ||
3140 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3141 },
3142 /*FromParent=*/true);
3143 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3144 ErrorFound = true;
3145 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3146 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3147 return;
3148 }
3149
3150 // Define implicit data-sharing attributes for task.
3151 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3152 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3153 !Stack->isLoopControlVariable(VD).first) {
3154 ImplicitFirstprivate.push_back(E);
3155 return;
3156 }
3157
3158 // Store implicitly used globals with declare target link for parent
3159 // target.
3160 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3161 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3162 Stack->addToParentTargetRegionLinkGlobals(E);
3163 return;
3164 }
3165 }
3166 }
3167 void VisitMemberExpr(MemberExpr *E) {
3168 if (E->isTypeDependent() || E->isValueDependent() ||
3169 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3170 return;
3171 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3172 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3173 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
3174 if (!FD)
3175 return;
3176 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3177 // Check if the variable has explicit DSA set and stop analysis if it
3178 // so.
3179 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3180 return;
3181
3182 if (isOpenMPTargetExecutionDirective(DKind) &&
3183 !Stack->isLoopControlVariable(FD).first &&
3184 !Stack->checkMappableExprComponentListsForDecl(
3185 FD, /*CurrentRegionOnly=*/true,
3186 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3187 StackComponents,
3188 OpenMPClauseKind) {
3189 return isa<CXXThisExpr>(
3190 cast<MemberExpr>(
3191 StackComponents.back().getAssociatedExpression())
3192 ->getBase()
3193 ->IgnoreParens());
3194 })) {
3195 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3196 // A bit-field cannot appear in a map clause.
3197 //
3198 if (FD->isBitField())
3199 return;
3200
3201 // Check to see if the member expression is referencing a class that
3202 // has already been explicitly mapped
3203 if (Stack->isClassPreviouslyMapped(TE->getType()))
3204 return;
3205
3206 OpenMPDefaultmapClauseModifier Modifier =
3207 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3208 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3209 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3210 ImplicitMap[Kind].emplace_back(E);
3211 return;
3212 }
3213
3214 SourceLocation ELoc = E->getExprLoc();
3215 // OpenMP [2.9.3.6, Restrictions, p.2]
3216 // A list item that appears in a reduction clause of the innermost
3217 // enclosing worksharing or parallel construct may not be accessed in
3218 // an explicit task.
3219 DVar = Stack->hasInnermostDSA(
3220 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3221 [](OpenMPDirectiveKind K) {
3222 return isOpenMPParallelDirective(K) ||
3223 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3224 },
3225 /*FromParent=*/true);
3226 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3227 ErrorFound = true;
3228 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3229 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3230 return;
3231 }
3232
3233 // Define implicit data-sharing attributes for task.
3234 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3235 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3236 !Stack->isLoopControlVariable(FD).first) {
3237 // Check if there is a captured expression for the current field in the
3238 // region. Do not mark it as firstprivate unless there is no captured
3239 // expression.
3240 // TODO: try to make it firstprivate.
3241 if (DVar.CKind != OMPC_unknown)
3242 ImplicitFirstprivate.push_back(E);
3243 }
3244 return;
3245 }
3246 if (isOpenMPTargetExecutionDirective(DKind)) {
3247 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3248 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3249 /*NoDiagnose=*/true))
3250 return;
3251 const auto *VD = cast<ValueDecl>(
3252 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3253 if (!Stack->checkMappableExprComponentListsForDecl(
3254 VD, /*CurrentRegionOnly=*/true,
3255 [&CurComponents](
3256 OMPClauseMappableExprCommon::MappableExprComponentListRef
3257 StackComponents,
3258 OpenMPClauseKind) {
3259 auto CCI = CurComponents.rbegin();
3260 auto CCE = CurComponents.rend();
3261 for (const auto &SC : llvm::reverse(StackComponents)) {
3262 // Do both expressions have the same kind?
3263 if (CCI->getAssociatedExpression()->getStmtClass() !=
3264 SC.getAssociatedExpression()->getStmtClass())
3265 if (!(isa<OMPArraySectionExpr>(
3266 SC.getAssociatedExpression()) &&
3267 isa<ArraySubscriptExpr>(
3268 CCI->getAssociatedExpression())))
3269 return false;
3270
3271 const Decl *CCD = CCI->getAssociatedDeclaration();
3272 const Decl *SCD = SC.getAssociatedDeclaration();
3273 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3274 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3275 if (SCD != CCD)
3276 return false;
3277 std::advance(CCI, 1);
3278 if (CCI == CCE)
3279 break;
3280 }
3281 return true;
3282 })) {
3283 Visit(E->getBase());
3284 }
3285 } else if (!TryCaptureCXXThisMembers) {
3286 Visit(E->getBase());
3287 }
3288 }
3289 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3290 for (OMPClause *C : S->clauses()) {
3291 // Skip analysis of arguments of implicitly defined firstprivate clause
3292 // for task|target directives.
3293 // Skip analysis of arguments of implicitly defined map clause for target
3294 // directives.
3295 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3296 C->isImplicit())) {
3297 for (Stmt *CC : C->children()) {
3298 if (CC)
3299 Visit(CC);
3300 }
3301 }
3302 }
3303 // Check implicitly captured variables.
3304 VisitSubCaptures(S);
3305 }
3306 void VisitStmt(Stmt *S) {
3307 for (Stmt *C : S->children()) {
3308 if (C) {
3309 // Check implicitly captured variables in the task-based directives to
3310 // check if they must be firstprivatized.
3311 Visit(C);
3312 }
3313 }
3314 }
3315
3316 void visitSubCaptures(CapturedStmt *S) {
3317 for (const CapturedStmt::Capture &Cap : S->captures()) {
3318 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3319 continue;
3320 VarDecl *VD = Cap.getCapturedVar();
3321 // Do not try to map the variable if it or its sub-component was mapped
3322 // already.
3323 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3324 Stack->checkMappableExprComponentListsForDecl(
3325 VD, /*CurrentRegionOnly=*/true,
3326 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3327 OpenMPClauseKind) { return true; }))
3328 continue;
3329 DeclRefExpr *DRE = buildDeclRefExpr(
3330 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3331 Cap.getLocation(), /*RefersToCapture=*/true);
3332 Visit(DRE);
3333 }
3334 }
3335 bool isErrorFound() const { return ErrorFound; }
3336 ArrayRef<Expr *> getImplicitFirstprivate() const {
3337 return ImplicitFirstprivate;
3338 }
3339 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3340 return ImplicitMap[Kind];
3341 }
3342 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3343 return VarsWithInheritedDSA;
3344 }
3345
3346 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3347 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3348 // Process declare target link variables for the target directives.
3349 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3350 for (DeclRefExpr *E : Stack->getLinkGlobals())
3351 Visit(E);
3352 }
3353 }
3354};
3355} // namespace
3356
3357void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3358 switch (DKind) {
3359 case OMPD_parallel:
3360 case OMPD_parallel_for:
3361 case OMPD_parallel_for_simd:
3362 case OMPD_parallel_sections:
3363 case OMPD_parallel_master:
3364 case OMPD_teams:
3365 case OMPD_teams_distribute:
3366 case OMPD_teams_distribute_simd: {
3367 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3368 QualType KmpInt32PtrTy =
3369 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3370 Sema::CapturedParamNameType Params[] = {
3371 std::make_pair(".global_tid.", KmpInt32PtrTy),
3372 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3373 std::make_pair(StringRef(), QualType()) // __context with shared vars
3374 };
3375 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3376 Params);
3377 break;
3378 }
3379 case OMPD_target_teams:
3380 case OMPD_target_parallel:
3381 case OMPD_target_parallel_for:
3382 case OMPD_target_parallel_for_simd:
3383 case OMPD_target_teams_distribute:
3384 case OMPD_target_teams_distribute_simd: {
3385 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3386 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3387 QualType KmpInt32PtrTy =
3388 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3389 QualType Args[] = {VoidPtrTy};
3390 FunctionProtoType::ExtProtoInfo EPI;
3391 EPI.Variadic = true;
3392 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3393 Sema::CapturedParamNameType Params[] = {
3394 std::make_pair(".global_tid.", KmpInt32Ty),
3395 std::make_pair(".part_id.", KmpInt32PtrTy),
3396 std::make_pair(".privates.", VoidPtrTy),
3397 std::make_pair(
3398 ".copy_fn.",
3399 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3400 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3401 std::make_pair(StringRef(), QualType()) // __context with shared vars
3402 };
3403 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3404 Params, /*OpenMPCaptureLevel=*/0);
3405 // Mark this captured region as inlined, because we don't use outlined
3406 // function directly.
3407 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3408 AlwaysInlineAttr::CreateImplicit(
3409 Context, {}, AttributeCommonInfo::AS_Keyword,
3410 AlwaysInlineAttr::Keyword_forceinline));
3411 Sema::CapturedParamNameType ParamsTarget[] = {
3412 std::make_pair(StringRef(), QualType()) // __context with shared vars
3413 };
3414 // Start a captured region for 'target' with no implicit parameters.
3415 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3416 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3417 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3418 std::make_pair(".global_tid.", KmpInt32PtrTy),
3419 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3420 std::make_pair(StringRef(), QualType()) // __context with shared vars
3421 };
3422 // Start a captured region for 'teams' or 'parallel'. Both regions have
3423 // the same implicit parameters.
3424 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3425 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3426 break;
3427 }
3428 case OMPD_target:
3429 case OMPD_target_simd: {
3430 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3431 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3432 QualType KmpInt32PtrTy =
3433 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3434 QualType Args[] = {VoidPtrTy};
3435 FunctionProtoType::ExtProtoInfo EPI;
3436 EPI.Variadic = true;
3437 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3438 Sema::CapturedParamNameType Params[] = {
3439 std::make_pair(".global_tid.", KmpInt32Ty),
3440 std::make_pair(".part_id.", KmpInt32PtrTy),
3441 std::make_pair(".privates.", VoidPtrTy),
3442 std::make_pair(
3443 ".copy_fn.",
3444 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3445 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3446 std::make_pair(StringRef(), QualType()) // __context with shared vars
3447 };
3448 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3449 Params, /*OpenMPCaptureLevel=*/0);
3450 // Mark this captured region as inlined, because we don't use outlined
3451 // function directly.
3452 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3453 AlwaysInlineAttr::CreateImplicit(
3454 Context, {}, AttributeCommonInfo::AS_Keyword,
3455 AlwaysInlineAttr::Keyword_forceinline));
3456 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3457 std::make_pair(StringRef(), QualType()),
3458 /*OpenMPCaptureLevel=*/1);
3459 break;
3460 }
3461 case OMPD_simd:
3462 case OMPD_for:
3463 case OMPD_for_simd:
3464 case OMPD_sections:
3465 case OMPD_section:
3466 case OMPD_single:
3467 case OMPD_master:
3468 case OMPD_critical:
3469 case OMPD_taskgroup:
3470 case OMPD_distribute:
3471 case OMPD_distribute_simd:
3472 case OMPD_ordered:
3473 case OMPD_atomic:
3474 case OMPD_target_data: {
3475 Sema::CapturedParamNameType Params[] = {
3476 std::make_pair(StringRef(), QualType()) // __context with shared vars
3477 };
3478 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3479 Params);
3480 break;
3481 }
3482 case OMPD_task: {
3483 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3484 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3485 QualType KmpInt32PtrTy =
3486 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3487 QualType Args[] = {VoidPtrTy};
3488 FunctionProtoType::ExtProtoInfo EPI;
3489 EPI.Variadic = true;
3490 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3491 Sema::CapturedParamNameType Params[] = {
3492 std::make_pair(".global_tid.", KmpInt32Ty),
3493 std::make_pair(".part_id.", KmpInt32PtrTy),
3494 std::make_pair(".privates.", VoidPtrTy),
3495 std::make_pair(
3496 ".copy_fn.",
3497 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3498 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3499 std::make_pair(StringRef(), QualType()) // __context with shared vars
3500 };
3501 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3502 Params);
3503 // Mark this captured region as inlined, because we don't use outlined
3504 // function directly.
3505 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3506 AlwaysInlineAttr::CreateImplicit(
3507 Context, {}, AttributeCommonInfo::AS_Keyword,
3508 AlwaysInlineAttr::Keyword_forceinline));
3509 break;
3510 }
3511 case OMPD_taskloop:
3512 case OMPD_taskloop_simd:
3513 case OMPD_master_taskloop:
3514 case OMPD_master_taskloop_simd: {
3515 QualType KmpInt32Ty =
3516 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3517 .withConst();
3518 QualType KmpUInt64Ty =
3519 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3520 .withConst();
3521 QualType KmpInt64Ty =
3522 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3523 .withConst();
3524 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3525 QualType KmpInt32PtrTy =
3526 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3527 QualType Args[] = {VoidPtrTy};
3528 FunctionProtoType::ExtProtoInfo EPI;
3529 EPI.Variadic = true;
3530 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3531 Sema::CapturedParamNameType Params[] = {
3532 std::make_pair(".global_tid.", KmpInt32Ty),
3533 std::make_pair(".part_id.", KmpInt32PtrTy),
3534 std::make_pair(".privates.", VoidPtrTy),
3535 std::make_pair(
3536 ".copy_fn.",
3537 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3538 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3539 std::make_pair(".lb.", KmpUInt64Ty),
3540 std::make_pair(".ub.", KmpUInt64Ty),
3541 std::make_pair(".st.", KmpInt64Ty),
3542 std::make_pair(".liter.", KmpInt32Ty),
3543 std::make_pair(".reductions.", VoidPtrTy),
3544 std::make_pair(StringRef(), QualType()) // __context with shared vars
3545 };
3546 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3547 Params);
3548 // Mark this captured region as inlined, because we don't use outlined
3549 // function directly.
3550 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3551 AlwaysInlineAttr::CreateImplicit(
3552 Context, {}, AttributeCommonInfo::AS_Keyword,
3553 AlwaysInlineAttr::Keyword_forceinline));
3554 break;
3555 }
3556 case OMPD_parallel_master_taskloop:
3557 case OMPD_parallel_master_taskloop_simd: {
3558 QualType KmpInt32Ty =
3559 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3560 .withConst();
3561 QualType KmpUInt64Ty =
3562 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3563 .withConst();
3564 QualType KmpInt64Ty =
3565 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3566 .withConst();
3567 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3568 QualType KmpInt32PtrTy =
3569 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3570 Sema::CapturedParamNameType ParamsParallel[] = {
3571 std::make_pair(".global_tid.", KmpInt32PtrTy),
3572 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3573 std::make_pair(StringRef(), QualType()) // __context with shared vars
3574 };
3575 // Start a captured region for 'parallel'.
3576 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3577 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3578 QualType Args[] = {VoidPtrTy};
3579 FunctionProtoType::ExtProtoInfo EPI;
3580 EPI.Variadic = true;
3581 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3582 Sema::CapturedParamNameType Params[] = {
3583 std::make_pair(".global_tid.", KmpInt32Ty),
3584 std::make_pair(".part_id.", KmpInt32PtrTy),
3585 std::make_pair(".privates.", VoidPtrTy),
3586 std::make_pair(
3587 ".copy_fn.",
3588 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3589 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3590 std::make_pair(".lb.", KmpUInt64Ty),
3591 std::make_pair(".ub.", KmpUInt64Ty),
3592 std::make_pair(".st.", KmpInt64Ty),
3593 std::make_pair(".liter.", KmpInt32Ty),
3594 std::make_pair(".reductions.", VoidPtrTy),
3595 std::make_pair(StringRef(), QualType()) // __context with shared vars
3596 };
3597 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3598 Params, /*OpenMPCaptureLevel=*/2);
3599 // Mark this captured region as inlined, because we don't use outlined
3600 // function directly.
3601 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3602 AlwaysInlineAttr::CreateImplicit(
3603 Context, {}, AttributeCommonInfo::AS_Keyword,
3604 AlwaysInlineAttr::Keyword_forceinline));
3605 break;
3606 }
3607 case OMPD_distribute_parallel_for_simd:
3608 case OMPD_distribute_parallel_for: {
3609 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3610 QualType KmpInt32PtrTy =
3611 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3612 Sema::CapturedParamNameType Params[] = {
3613 std::make_pair(".global_tid.", KmpInt32PtrTy),
3614 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3615 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3616 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3617 std::make_pair(StringRef(), QualType()) // __context with shared vars
3618 };
3619 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3620 Params);
3621 break;
3622 }
3623 case OMPD_target_teams_distribute_parallel_for:
3624 case OMPD_target_teams_distribute_parallel_for_simd: {
3625 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3626 QualType KmpInt32PtrTy =
3627 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3628 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3629
3630 QualType Args[] = {VoidPtrTy};
3631 FunctionProtoType::ExtProtoInfo EPI;
3632 EPI.Variadic = true;
3633 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3634 Sema::CapturedParamNameType Params[] = {
3635 std::make_pair(".global_tid.", KmpInt32Ty),
3636 std::make_pair(".part_id.", KmpInt32PtrTy),
3637 std::make_pair(".privates.", VoidPtrTy),
3638 std::make_pair(
3639 ".copy_fn.",
3640 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3641 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3642 std::make_pair(StringRef(), QualType()) // __context with shared vars
3643 };
3644 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3645 Params, /*OpenMPCaptureLevel=*/0);
3646 // Mark this captured region as inlined, because we don't use outlined
3647 // function directly.
3648 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3649 AlwaysInlineAttr::CreateImplicit(
3650 Context, {}, AttributeCommonInfo::AS_Keyword,
3651 AlwaysInlineAttr::Keyword_forceinline));
3652 Sema::CapturedParamNameType ParamsTarget[] = {
3653 std::make_pair(StringRef(), QualType()) // __context with shared vars
3654 };
3655 // Start a captured region for 'target' with no implicit parameters.
3656 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3657 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3658
3659 Sema::CapturedParamNameType ParamsTeams[] = {
3660 std::make_pair(".global_tid.", KmpInt32PtrTy),
3661 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3662 std::make_pair(StringRef(), QualType()) // __context with shared vars
3663 };
3664 // Start a captured region for 'target' with no implicit parameters.
3665 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3666 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3667
3668 Sema::CapturedParamNameType ParamsParallel[] = {
3669 std::make_pair(".global_tid.", KmpInt32PtrTy),
3670 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3671 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3672 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3673 std::make_pair(StringRef(), QualType()) // __context with shared vars
3674 };
3675 // Start a captured region for 'teams' or 'parallel'. Both regions have
3676 // the same implicit parameters.
3677 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3678 ParamsParallel, /*OpenMPCaptureLevel=*/3);
3679 break;
3680 }
3681
3682 case OMPD_teams_distribute_parallel_for:
3683 case OMPD_teams_distribute_parallel_for_simd: {
3684 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3685 QualType KmpInt32PtrTy =
3686 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3687
3688 Sema::CapturedParamNameType ParamsTeams[] = {
3689 std::make_pair(".global_tid.", KmpInt32PtrTy),
3690 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3691 std::make_pair(StringRef(), QualType()) // __context with shared vars
3692 };
3693 // Start a captured region for 'target' with no implicit parameters.
3694 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3695 ParamsTeams, /*OpenMPCaptureLevel=*/0);
3696
3697 Sema::CapturedParamNameType ParamsParallel[] = {
3698 std::make_pair(".global_tid.", KmpInt32PtrTy),
3699 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3700 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3701 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3702 std::make_pair(StringRef(), QualType()) // __context with shared vars
3703 };
3704 // Start a captured region for 'teams' or 'parallel'. Both regions have
3705 // the same implicit parameters.
3706 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3707 ParamsParallel, /*OpenMPCaptureLevel=*/1);
3708 break;
3709 }
3710 case OMPD_target_update:
3711 case OMPD_target_enter_data:
3712 case OMPD_target_exit_data: {
3713 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3714 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3715 QualType KmpInt32PtrTy =
3716 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3717 QualType Args[] = {VoidPtrTy};
3718 FunctionProtoType::ExtProtoInfo EPI;
3719 EPI.Variadic = true;
3720 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3721 Sema::CapturedParamNameType Params[] = {
3722 std::make_pair(".global_tid.", KmpInt32Ty),
3723 std::make_pair(".part_id.", KmpInt32PtrTy),
3724 std::make_pair(".privates.", VoidPtrTy),
3725 std::make_pair(
3726 ".copy_fn.",
3727 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3728 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3729 std::make_pair(StringRef(), QualType()) // __context with shared vars
3730 };
3731 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
3732 Params);
3733 // Mark this captured region as inlined, because we don't use outlined
3734 // function directly.
3735 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3736 AlwaysInlineAttr::CreateImplicit(
3737 Context, {}, AttributeCommonInfo::AS_Keyword,
3738 AlwaysInlineAttr::Keyword_forceinline));
3739 break;
3740 }
3741 case OMPD_threadprivate:
3742 case OMPD_allocate:
3743 case OMPD_taskyield:
3744 case OMPD_barrier:
3745 case OMPD_taskwait:
3746 case OMPD_cancellation_point:
3747 case OMPD_cancel:
3748 case OMPD_flush:
3749 case OMPD_depobj:
3750 case OMPD_declare_reduction:
3751 case OMPD_declare_mapper:
3752 case OMPD_declare_simd:
3753 case OMPD_declare_target:
3754 case OMPD_end_declare_target:
3755 case OMPD_requires:
3756 case OMPD_declare_variant:
3757 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 3757)
;
3758 case OMPD_unknown:
3759 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 3759)
;
3760 }
3761}
3762
3763int Sema::getNumberOfConstructScopes(unsigned Level) const {
3764 return getOpenMPCaptureLevels(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
3765}
3766
3767int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
3768 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3769 getOpenMPCaptureRegions(CaptureRegions, DKind);
3770 return CaptureRegions.size();
3771}
3772
3773static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
3774 Expr *CaptureExpr, bool WithInit,
3775 bool AsExpression) {
3776 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 3776, __PRETTY_FUNCTION__))
;
3777 ASTContext &C = S.getASTContext();
3778 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
3779 QualType Ty = Init->getType();
3780 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
3781 if (S.getLangOpts().CPlusPlus) {
3782 Ty = C.getLValueReferenceType(Ty);
3783 } else {
3784 Ty = C.getPointerType(Ty);
3785 ExprResult Res =
3786 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3787 if (!Res.isUsable())
3788 return nullptr;
3789 Init = Res.get();
3790 }
3791 WithInit = true;
3792 }
3793 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
3794 CaptureExpr->getBeginLoc());
3795 if (!WithInit)
3796 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3797 S.CurContext->addHiddenDecl(CED);
3798 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
3799 return CED;
3800}
3801
3802static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3803 bool WithInit) {
3804 OMPCapturedExprDecl *CD;
3805 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
3806 CD = cast<OMPCapturedExprDecl>(VD);
3807 else
3808 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3809 /*AsExpression=*/false);
3810 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3811 CaptureExpr->getExprLoc());
3812}
3813
3814static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
3815 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
3816 if (!Ref) {
3817 OMPCapturedExprDecl *CD = buildCaptureDecl(
3818 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3819 /*WithInit=*/true, /*AsExpression=*/true);
3820 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3821 CaptureExpr->getExprLoc());
3822 }
3823 ExprResult Res = Ref;
3824 if (!S.getLangOpts().CPlusPlus &&
3825 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
3826 Ref->getType()->isPointerType()) {
3827 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
3828 if (!Res.isUsable())
3829 return ExprError();
3830 }
3831 return S.DefaultLvalueConversion(Res.get());
3832}
3833
3834namespace {
3835// OpenMP directives parsed in this section are represented as a
3836// CapturedStatement with an associated statement. If a syntax error
3837// is detected during the parsing of the associated statement, the
3838// compiler must abort processing and close the CapturedStatement.
3839//
3840// Combined directives such as 'target parallel' have more than one
3841// nested CapturedStatements. This RAII ensures that we unwind out
3842// of all the nested CapturedStatements when an error is found.
3843class CaptureRegionUnwinderRAII {
3844private:
3845 Sema &S;
3846 bool &ErrorFound;
3847 OpenMPDirectiveKind DKind = OMPD_unknown;
3848
3849public:
3850 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3851 OpenMPDirectiveKind DKind)
3852 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3853 ~CaptureRegionUnwinderRAII() {
3854 if (ErrorFound) {
3855 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3856 while (--ThisCaptureLevel >= 0)
3857 S.ActOnCapturedRegionError();
3858 }
3859 }
3860};
3861} // namespace
3862
3863void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
3864 // Capture variables captured by reference in lambdas for target-based
3865 // directives.
3866 if (!CurContext->isDependentContext() &&
3867 (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) ||
3868 isOpenMPTargetDataManagementDirective(
3869 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()))) {
3870 QualType Type = V->getType();
3871 if (const auto *RD = Type.getCanonicalType()
3872 .getNonReferenceType()
3873 ->getAsCXXRecordDecl()) {
3874 bool SavedForceCaptureByReferenceInTargetExecutable =
3875 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceCaptureByReferenceInTargetExecutable();
3876 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
3877 /*V=*/true);
3878 if (RD->isLambda()) {
3879 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3880 FieldDecl *ThisCapture;
3881 RD->getCaptureFields(Captures, ThisCapture);
3882 for (const LambdaCapture &LC : RD->captures()) {
3883 if (LC.getCaptureKind() == LCK_ByRef) {
3884 VarDecl *VD = LC.getCapturedVar();
3885 DeclContext *VDC = VD->getDeclContext();
3886 if (!VDC->Encloses(CurContext))
3887 continue;
3888 MarkVariableReferenced(LC.getLocation(), VD);
3889 } else if (LC.getCaptureKind() == LCK_This) {
3890 QualType ThisTy = getCurrentThisType();
3891 if (!ThisTy.isNull() &&
3892 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
3893 CheckCXXThisCapture(LC.getLocation());
3894 }
3895 }
3896 }
3897 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceCaptureByReferenceInTargetExecutable(
3898 SavedForceCaptureByReferenceInTargetExecutable);
3899 }
3900 }
3901}
3902
3903static bool checkOrderedOrderSpecified(Sema &S,
3904 const ArrayRef<OMPClause *> Clauses) {
3905 const OMPOrderedClause *Ordered = nullptr;
3906 const OMPOrderClause *Order = nullptr;
3907
3908 for (const OMPClause *Clause : Clauses) {
3909 if (Clause->getClauseKind() == OMPC_ordered)
3910 Ordered = cast<OMPOrderedClause>(Clause);
3911 else if (Clause->getClauseKind() == OMPC_order) {
3912 Order = cast<OMPOrderClause>(Clause);
3913 if (Order->getKind() != OMPC_ORDER_concurrent)
3914 Order = nullptr;
3915 }
3916 if (Ordered && Order)
3917 break;
3918 }
3919
3920 if (Ordered && Order) {
3921 S.Diag(Order->getKindKwLoc(),
3922 diag::err_omp_simple_clause_incompatible_with_ordered)
3923 << getOpenMPClauseName(OMPC_order)
3924 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
3925 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
3926 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
3927 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
3928 return true;
3929 }
3930 return false;
3931}
3932
3933StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
3934 ArrayRef<OMPClause *> Clauses) {
3935 bool ErrorFound = false;
3936 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3937 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
3938 if (!S.isUsable()) {
3939 ErrorFound = true;
3940 return StmtError();
3941 }
3942
3943 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3944 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
3945 OMPOrderedClause *OC = nullptr;
3946 OMPScheduleClause *SC = nullptr;
3947 SmallVector<const OMPLinearClause *, 4> LCs;
3948 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
3949 // This is required for proper codegen.
3950 for (OMPClause *Clause : Clauses) {
3951 if (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
3952 Clause->getClauseKind() == OMPC_in_reduction) {
3953 // Capture taskgroup task_reduction descriptors inside the tasking regions
3954 // with the corresponding in_reduction items.
3955 auto *IRC = cast<OMPInReductionClause>(Clause);
3956 for (Expr *E : IRC->taskgroup_descriptors())
3957 if (E)
3958 MarkDeclarationsReferencedInExpr(E);
3959 }
3960 if (isOpenMPPrivate(Clause->getClauseKind()) ||
3961 Clause->getClauseKind() == OMPC_copyprivate ||
3962 (getLangOpts().OpenMPUseTLS &&
3963 getASTContext().getTargetInfo().isTLSSupported() &&
3964 Clause->getClauseKind() == OMPC_copyin)) {
3965 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
3966 // Mark all variables in private list clauses as used in inner region.
3967 for (Stmt *VarRef : Clause->children()) {
3968 if (auto *E = cast_or_null<Expr>(VarRef)) {
3969 MarkDeclarationsReferencedInExpr(E);
3970 }
3971 }
3972 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
3973 } else if (CaptureRegions.size() > 1 ||
3974 CaptureRegions.back() != OMPD_unknown) {
3975 if (auto *C = OMPClauseWithPreInit::get(Clause))
3976 PICs.push_back(C);
3977 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
3978 if (Expr *E = C->getPostUpdateExpr())
3979 MarkDeclarationsReferencedInExpr(E);
3980 }
3981 }
3982 if (Clause->getClauseKind() == OMPC_schedule)
3983 SC = cast<OMPScheduleClause>(Clause);
3984 else if (Clause->getClauseKind() == OMPC_ordered)
3985 OC = cast<OMPOrderedClause>(Clause);
3986 else if (Clause->getClauseKind() == OMPC_linear)
3987 LCs.push_back(cast<OMPLinearClause>(Clause));
3988 }
3989 // Capture allocator expressions if used.
3990 for (Expr *E : DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerAllocators())
3991 MarkDeclarationsReferencedInExpr(E);
3992 // OpenMP, 2.7.1 Loop Construct, Restrictions
3993 // The nonmonotonic modifier cannot be specified if an ordered clause is
3994 // specified.
3995 if (SC &&
3996 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3997 SC->getSecondScheduleModifier() ==
3998 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3999 OC) {
4000 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4001 ? SC->getFirstScheduleModifierLoc()
4002 : SC->getSecondScheduleModifierLoc(),
4003 diag::err_omp_simple_clause_incompatible_with_ordered)
4004 << getOpenMPClauseName(OMPC_schedule)
4005 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4006 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4007 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4008 ErrorFound = true;
4009 }
4010 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4011 // If an order(concurrent) clause is present, an ordered clause may not appear
4012 // on the same directive.
4013 if (checkOrderedOrderSpecified(*this, Clauses))
4014 ErrorFound = true;
4015 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4016 for (const OMPLinearClause *C : LCs) {
4017 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4018 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4019 }
4020 ErrorFound = true;
4021 }
4022 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
4023 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
4024 OC->getNumForLoops()) {
4025 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4026 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
4027 ErrorFound = true;
4028 }
4029 if (ErrorFound) {
4030 return StmtError();
4031 }
4032 StmtResult SR = S;
4033 unsigned CompletedRegions = 0;
4034 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4035 // Mark all variables in private list clauses as used in inner region.
4036 // Required for proper codegen of combined directives.
4037 // TODO: add processing for other clauses.
4038 if (ThisCaptureRegion != OMPD_unknown) {
4039 for (const clang::OMPClauseWithPreInit *C : PICs) {
4040 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4041 // Find the particular capture region for the clause if the
4042 // directive is a combined one with multiple capture regions.
4043 // If the directive is not a combined one, the capture region
4044 // associated with the clause is OMPD_unknown and is generated
4045 // only once.
4046 if (CaptureRegion == ThisCaptureRegion ||
4047 CaptureRegion == OMPD_unknown) {
4048 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4049 for (Decl *D : DS->decls())
4050 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4051 }
4052 }
4053 }
4054 }
4055 if (++CompletedRegions == CaptureRegions.size())
4056 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setBodyComplete();
4057 SR = ActOnCapturedRegionEnd(SR.get());
4058 }
4059 return SR;
4060}
4061
4062static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4063 OpenMPDirectiveKind CancelRegion,
4064 SourceLocation StartLoc) {
4065 // CancelRegion is only needed for cancel and cancellation_point.
4066 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4067 return false;
4068
4069 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4070 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4071 return false;
4072
4073 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4074 << getOpenMPDirectiveName(CancelRegion);
4075 return true;
4076}
4077
4078static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4079 OpenMPDirectiveKind CurrentRegion,
4080 const DeclarationNameInfo &CurrentName,
4081 OpenMPDirectiveKind CancelRegion,
4082 SourceLocation StartLoc) {
4083 if (Stack->getCurScope()) {
4084 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4085 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4086 bool NestingProhibited = false;
4087 bool CloseNesting = true;
4088 bool OrphanSeen = false;
4089 enum {
4090 NoRecommend,
4091 ShouldBeInParallelRegion,
4092 ShouldBeInOrderedRegion,
4093 ShouldBeInTargetRegion,
4094 ShouldBeInTeamsRegion
4095 } Recommend = NoRecommend;
4096 if (isOpenMPSimdDirective(ParentRegion) &&
4097 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4098 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4099 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) {
4100 // OpenMP [2.16, Nesting of Regions]
4101 // OpenMP constructs may not be nested inside a simd region.
4102 // OpenMP [2.8.1,simd Construct, Restrictions]
4103 // An ordered construct with the simd clause is the only OpenMP
4104 // construct that can appear in the simd region.
4105 // Allowing a SIMD construct nested in another SIMD construct is an
4106 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4107 // message.
4108 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4109 // The only OpenMP constructs that can be encountered during execution of
4110 // a simd region are the atomic construct, the loop construct, the simd
4111 // construct and the ordered construct with the simd clause.
4112 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4113 ? diag::err_omp_prohibited_region_simd
4114 : diag::warn_omp_nesting_simd)
4115 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4116 return CurrentRegion != OMPD_simd;
4117 }
4118 if (ParentRegion == OMPD_atomic) {
4119 // OpenMP [2.16, Nesting of Regions]
4120 // OpenMP constructs may not be nested inside an atomic region.
4121 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4122 return true;
4123 }
4124 if (CurrentRegion == OMPD_section) {
4125 // OpenMP [2.7.2, sections Construct, Restrictions]
4126 // Orphaned section directives are prohibited. That is, the section
4127 // directives must appear within the sections construct and must not be
4128 // encountered elsewhere in the sections region.
4129 if (ParentRegion != OMPD_sections &&
4130 ParentRegion != OMPD_parallel_sections) {
4131 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4132 << (ParentRegion != OMPD_unknown)
4133 << getOpenMPDirectiveName(ParentRegion);
4134 return true;
4135 }
4136 return false;
4137 }
4138 // Allow some constructs (except teams and cancellation constructs) to be
4139 // orphaned (they could be used in functions, called from OpenMP regions
4140 // with the required preconditions).
4141 if (ParentRegion == OMPD_unknown &&
4142 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4143 CurrentRegion != OMPD_cancellation_point &&
4144 CurrentRegion != OMPD_cancel)
4145 return false;
4146 if (CurrentRegion == OMPD_cancellation_point ||
4147 CurrentRegion == OMPD_cancel) {
4148 // OpenMP [2.16, Nesting of Regions]
4149 // A cancellation point construct for which construct-type-clause is
4150 // taskgroup must be nested inside a task construct. A cancellation
4151 // point construct for which construct-type-clause is not taskgroup must
4152 // be closely nested inside an OpenMP construct that matches the type
4153 // specified in construct-type-clause.
4154 // A cancel construct for which construct-type-clause is taskgroup must be
4155 // nested inside a task construct. A cancel construct for which
4156 // construct-type-clause is not taskgroup must be closely nested inside an
4157 // OpenMP construct that matches the type specified in
4158 // construct-type-clause.
4159 NestingProhibited =
4160 !((CancelRegion == OMPD_parallel &&
4161 (ParentRegion == OMPD_parallel ||
4162 ParentRegion == OMPD_target_parallel)) ||
4163 (CancelRegion == OMPD_for &&
4164 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4165 ParentRegion == OMPD_target_parallel_for ||
4166 ParentRegion == OMPD_distribute_parallel_for ||
4167 ParentRegion == OMPD_teams_distribute_parallel_for ||
4168 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4169 (CancelRegion == OMPD_taskgroup &&
4170 (ParentRegion == OMPD_task ||
4171 (SemaRef.getLangOpts().OpenMP >= 50 &&
4172 (ParentRegion == OMPD_taskloop ||
4173 ParentRegion == OMPD_master_taskloop ||
4174 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4175 (CancelRegion == OMPD_sections &&
4176 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4177 ParentRegion == OMPD_parallel_sections)));
4178 OrphanSeen = ParentRegion == OMPD_unknown;
4179 } else if (CurrentRegion == OMPD_master) {
4180 // OpenMP [2.16, Nesting of Regions]
4181 // A master region may not be closely nested inside a worksharing,
4182 // atomic, or explicit task region.
4183 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4184 isOpenMPTaskingDirective(ParentRegion);
4185 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4186 // OpenMP [2.16, Nesting of Regions]
4187 // A critical region may not be nested (closely or otherwise) inside a
4188 // critical region with the same name. Note that this restriction is not
4189 // sufficient to prevent deadlock.
4190 SourceLocation PreviousCriticalLoc;
4191 bool DeadLock = Stack->hasDirective(
4192 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4193 const DeclarationNameInfo &DNI,
4194 SourceLocation Loc) {
4195 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4196 PreviousCriticalLoc = Loc;
4197 return true;
4198 }
4199 return false;
4200 },
4201 false /* skip top directive */);
4202 if (DeadLock) {
4203 SemaRef.Diag(StartLoc,
4204 diag::err_omp_prohibited_region_critical_same_name)
4205 << CurrentName.getName();
4206 if (PreviousCriticalLoc.isValid())
4207 SemaRef.Diag(PreviousCriticalLoc,
4208 diag::note_omp_previous_critical_region);
4209 return true;
4210 }
4211 } else if (CurrentRegion == OMPD_barrier) {
4212 // OpenMP [2.16, Nesting of Regions]
4213 // A barrier region may not be closely nested inside a worksharing,
4214 // explicit task, critical, ordered, atomic, or master region.
4215 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4216 isOpenMPTaskingDirective(ParentRegion) ||
4217 ParentRegion == OMPD_master ||
4218 ParentRegion == OMPD_parallel_master ||
4219 ParentRegion == OMPD_critical ||
4220 ParentRegion == OMPD_ordered;
4221 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4222 !isOpenMPParallelDirective(CurrentRegion) &&
4223 !isOpenMPTeamsDirective(CurrentRegion)) {
4224 // OpenMP [2.16, Nesting of Regions]
4225 // A worksharing region may not be closely nested inside a worksharing,
4226 // explicit task, critical, ordered, atomic, or master region.
4227 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4228 isOpenMPTaskingDirective(ParentRegion) ||
4229 ParentRegion == OMPD_master ||
4230 ParentRegion == OMPD_parallel_master ||
4231 ParentRegion == OMPD_critical ||
4232 ParentRegion == OMPD_ordered;
4233 Recommend = ShouldBeInParallelRegion;
4234 } else if (CurrentRegion == OMPD_ordered) {
4235 // OpenMP [2.16, Nesting of Regions]
4236 // An ordered region may not be closely nested inside a critical,
4237 // atomic, or explicit task region.
4238 // An ordered region must be closely nested inside a loop region (or
4239 // parallel loop region) with an ordered clause.
4240 // OpenMP [2.8.1,simd Construct, Restrictions]
4241 // An ordered construct with the simd clause is the only OpenMP construct
4242 // that can appear in the simd region.
4243 NestingProhibited = ParentRegion == OMPD_critical ||
4244 isOpenMPTaskingDirective(ParentRegion) ||
4245 !(isOpenMPSimdDirective(ParentRegion) ||
4246 Stack->isParentOrderedRegion());
4247 Recommend = ShouldBeInOrderedRegion;
4248 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4249 // OpenMP [2.16, Nesting of Regions]
4250 // If specified, a teams construct must be contained within a target
4251 // construct.
4252 NestingProhibited =
4253 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4254 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4255 ParentRegion != OMPD_target);
4256 OrphanSeen = ParentRegion == OMPD_unknown;
4257 Recommend = ShouldBeInTargetRegion;
4258 }
4259 if (!NestingProhibited &&
4260 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4261 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4262 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4263 // OpenMP [2.16, Nesting of Regions]
4264 // distribute, parallel, parallel sections, parallel workshare, and the
4265 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4266 // constructs that can be closely nested in the teams region.
4267 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4268 !isOpenMPDistributeDirective(CurrentRegion);
4269 Recommend = ShouldBeInParallelRegion;
4270 }
4271 if (!NestingProhibited &&
4272 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4273 // OpenMP 4.5 [2.17 Nesting of Regions]
4274 // The region associated with the distribute construct must be strictly
4275 // nested inside a teams region
4276 NestingProhibited =
4277 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4278 Recommend = ShouldBeInTeamsRegion;
4279 }
4280 if (!NestingProhibited &&
4281 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4282 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4283 // OpenMP 4.5 [2.17 Nesting of Regions]
4284 // If a target, target update, target data, target enter data, or
4285 // target exit data construct is encountered during execution of a
4286 // target region, the behavior is unspecified.
4287 NestingProhibited = Stack->hasDirective(
4288 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4289 SourceLocation) {
4290 if (isOpenMPTargetExecutionDirective(K)) {
4291 OffendingRegion = K;
4292 return true;
4293 }
4294 return false;
4295 },
4296 false /* don't skip top directive */);
4297 CloseNesting = false;
4298 }
4299 if (NestingProhibited) {
4300 if (OrphanSeen) {
4301 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4302 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4303 } else {
4304 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4305 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4306 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4307 }
4308 return true;
4309 }
4310 }
4311 return false;
4312}
4313
4314struct Kind2Unsigned {
4315 using argument_type = OpenMPDirectiveKind;
4316 unsigned operator()(argument_type DK) { return unsigned(DK); }
4317};
4318static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4319 ArrayRef<OMPClause *> Clauses,
4320 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4321 bool ErrorFound = false;
4322 unsigned NamedModifiersNumber = 0;
4323 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4324 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1);
4325 SmallVector<SourceLocation, 4> NameModifierLoc;
4326 for (const OMPClause *C : Clauses) {
4327 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4328 // At most one if clause without a directive-name-modifier can appear on
4329 // the directive.
4330 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4331 if (FoundNameModifiers[CurNM]) {
4332 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4333 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4334 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4335 ErrorFound = true;
4336 } else if (CurNM != OMPD_unknown) {
4337 NameModifierLoc.push_back(IC->getNameModifierLoc());
4338 ++NamedModifiersNumber;
4339 }
4340 FoundNameModifiers[CurNM] = IC;
4341 if (CurNM == OMPD_unknown)
4342 continue;
4343 // Check if the specified name modifier is allowed for the current
4344 // directive.
4345 // At most one if clause with the particular directive-name-modifier can
4346 // appear on the directive.
4347 bool MatchFound = false;
4348 for (auto NM : AllowedNameModifiers) {
4349 if (CurNM == NM) {
4350 MatchFound = true;
4351 break;
4352 }
4353 }
4354 if (!MatchFound) {
4355 S.Diag(IC->getNameModifierLoc(),
4356 diag::err_omp_wrong_if_directive_name_modifier)
4357 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4358 ErrorFound = true;
4359 }
4360 }
4361 }
4362 // If any if clause on the directive includes a directive-name-modifier then
4363 // all if clauses on the directive must include a directive-name-modifier.
4364 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4365 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4366 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4367 diag::err_omp_no_more_if_clause);
4368 } else {
4369 std::string Values;
4370 std::string Sep(", ");
4371 unsigned AllowedCnt = 0;
4372 unsigned TotalAllowedNum =
4373 AllowedNameModifiers.size() - NamedModifiersNumber;
4374 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4375 ++Cnt) {
4376 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4377 if (!FoundNameModifiers[NM]) {
4378 Values += "'";
4379 Values += getOpenMPDirectiveName(NM);
4380 Values += "'";
4381 if (AllowedCnt + 2 == TotalAllowedNum)
4382 Values += " or ";
4383 else if (AllowedCnt + 1 != TotalAllowedNum)
4384 Values += Sep;
4385 ++AllowedCnt;
4386 }
4387 }
4388 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4389 diag::err_omp_unnamed_if_clause)
4390 << (TotalAllowedNum > 1) << Values;
4391 }
4392 for (SourceLocation Loc : NameModifierLoc) {
4393 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4394 }
4395 ErrorFound = true;
4396 }
4397 return ErrorFound;
4398}
4399
4400static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4401 SourceLocation &ELoc,
4402 SourceRange &ERange,
4403 bool AllowArraySection) {
4404 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4405 RefExpr->containsUnexpandedParameterPack())
4406 return std::make_pair(nullptr, true);
4407
4408 // OpenMP [3.1, C/C++]
4409 // A list item is a variable name.
4410 // OpenMP [2.9.3.3, Restrictions, p.1]
4411 // A variable that is part of another variable (as an array or
4412 // structure element) cannot appear in a private clause.
4413 RefExpr = RefExpr->IgnoreParens();
4414 enum {
4415 NoArrayExpr = -1,
4416 ArraySubscript = 0,
4417 OMPArraySection = 1
4418 } IsArrayExpr = NoArrayExpr;
4419 if (AllowArraySection) {
4420 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4421 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4422 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4423 Base = TempASE->getBase()->IgnoreParenImpCasts();
4424 RefExpr = Base;
4425 IsArrayExpr = ArraySubscript;
4426 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4427 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4428 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4429 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4430 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4431 Base = TempASE->getBase()->IgnoreParenImpCasts();
4432 RefExpr = Base;
4433 IsArrayExpr = OMPArraySection;
4434 }
4435 }
4436 ELoc = RefExpr->getExprLoc();
4437 ERange = RefExpr->getSourceRange();
4438 RefExpr = RefExpr->IgnoreParenImpCasts();
4439 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4440 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4441 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4442 (S.getCurrentThisType().isNull() || !ME ||
4443 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4444 !isa<FieldDecl>(ME->getMemberDecl()))) {
4445 if (IsArrayExpr != NoArrayExpr) {
4446 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4447 << ERange;
4448 } else {
4449 S.Diag(ELoc,
4450 AllowArraySection
4451 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4452 : diag::err_omp_expected_var_name_member_expr)
4453 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4454 }
4455 return std::make_pair(nullptr, false);
4456 }
4457 return std::make_pair(
4458 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4459}
4460
4461static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4462 ArrayRef<OMPClause *> Clauses) {
4463 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4464, __PRETTY_FUNCTION__))
4464 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4464, __PRETTY_FUNCTION__))
;
4465 auto AllocateRange =
4466 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4467 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4468 DeclToCopy;
4469 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4470 return isOpenMPPrivate(C->getClauseKind());
4471 });
4472 for (OMPClause *Cl : PrivateRange) {
4473 MutableArrayRef<Expr *>::iterator I, It, Et;
4474 if (Cl->getClauseKind() == OMPC_private) {
4475 auto *PC = cast<OMPPrivateClause>(Cl);
4476 I = PC->private_copies().begin();
4477 It = PC->varlist_begin();
4478 Et = PC->varlist_end();
4479 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4480 auto *PC = cast<OMPFirstprivateClause>(Cl);
4481 I = PC->private_copies().begin();
4482 It = PC->varlist_begin();
4483 Et = PC->varlist_end();
4484 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4485 auto *PC = cast<OMPLastprivateClause>(Cl);
4486 I = PC->private_copies().begin();
4487 It = PC->varlist_begin();
4488 Et = PC->varlist_end();
4489 } else if (Cl->getClauseKind() == OMPC_linear) {
4490 auto *PC = cast<OMPLinearClause>(Cl);
4491 I = PC->privates().begin();
4492 It = PC->varlist_begin();
4493 Et = PC->varlist_end();
4494 } else if (Cl->getClauseKind() == OMPC_reduction) {
4495 auto *PC = cast<OMPReductionClause>(Cl);
4496 I = PC->privates().begin();
4497 It = PC->varlist_begin();
4498 Et = PC->varlist_end();
4499 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4500 auto *PC = cast<OMPTaskReductionClause>(Cl);
4501 I = PC->privates().begin();
4502 It = PC->varlist_begin();
4503 Et = PC->varlist_end();
4504 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4505 auto *PC = cast<OMPInReductionClause>(Cl);
4506 I = PC->privates().begin();
4507 It = PC->varlist_begin();
4508 Et = PC->varlist_end();
4509 } else {
4510 llvm_unreachable("Expected private clause.")::llvm::llvm_unreachable_internal("Expected private clause.",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4510)
;
4511 }
4512 for (Expr *E : llvm::make_range(It, Et)) {
4513 if (!*I) {
4514 ++I;
4515 continue;
4516 }
4517 SourceLocation ELoc;
4518 SourceRange ERange;
4519 Expr *SimpleRefExpr = E;
4520 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4521 /*AllowArraySection=*/true);
4522 DeclToCopy.try_emplace(Res.first,
4523 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4524 ++I;
4525 }
4526 }
4527 for (OMPClause *C : AllocateRange) {
4528 auto *AC = cast<OMPAllocateClause>(C);
4529 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4530 getAllocatorKind(S, Stack, AC->getAllocator());
4531 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4532 // For task, taskloop or target directives, allocation requests to memory
4533 // allocators with the trait access set to thread result in unspecified
4534 // behavior.
4535 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4536 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4537 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4538 S.Diag(AC->getAllocator()->getExprLoc(),
4539 diag::warn_omp_allocate_thread_on_task_target_directive)
4540 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4541 }
4542 for (Expr *E : AC->varlists()) {
4543 SourceLocation ELoc;
4544 SourceRange ERange;
4545 Expr *SimpleRefExpr = E;
4546 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4547 ValueDecl *VD = Res.first;
4548 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4549 if (!isOpenMPPrivate(Data.CKind)) {
4550 S.Diag(E->getExprLoc(),
4551 diag::err_omp_expected_private_copy_for_allocate);
4552 continue;
4553 }
4554 VarDecl *PrivateVD = DeclToCopy[VD];
4555 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4556 AllocatorKind, AC->getAllocator()))
4557 continue;
4558 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4559 E->getSourceRange());
4560 }
4561 }
4562}
4563
4564StmtResult Sema::ActOnOpenMPExecutableDirective(
4565 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4566 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4567 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4568 StmtResult Res = StmtError();
4569 // First check CancelRegion which is then used in checkNestingOfRegions.
4570 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4571 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
4572 StartLoc))
4573 return StmtError();
4574
4575 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4576 VarsWithInheritedDSAType VarsWithInheritedDSA;
4577 bool ErrorFound = false;
4578 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4579 if (AStmt && !CurContext->isDependentContext()) {
4580 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4580, __PRETTY_FUNCTION__))
;
4581
4582 // Check default data sharing attributes for referenced variables.
4583 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
4584 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4585 Stmt *S = AStmt;
4586 while (--ThisCaptureLevel >= 0)
4587 S = cast<CapturedStmt>(S)->getCapturedStmt();
4588 DSAChecker.Visit(S);
4589 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4590 !isOpenMPTaskingDirective(Kind)) {
4591 // Visit subcaptures to generate implicit clauses for captured vars.
4592 auto *CS = cast<CapturedStmt>(AStmt);
4593 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4594 getOpenMPCaptureRegions(CaptureRegions, Kind);
4595 // Ignore outer tasking regions for target directives.
4596 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4597 CS = cast<CapturedStmt>(CS->getCapturedStmt());
4598 DSAChecker.visitSubCaptures(CS);
4599 }
4600 if (DSAChecker.isErrorFound())
4601 return StmtError();
4602 // Generate list of implicitly defined firstprivate variables.
4603 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4604
4605 SmallVector<Expr *, 4> ImplicitFirstprivates(
4606 DSAChecker.getImplicitFirstprivate().begin(),
4607 DSAChecker.getImplicitFirstprivate().end());
4608 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
4609 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
4610 ArrayRef<Expr *> ImplicitMap =
4611 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
4612 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
4613 }
4614 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
4615 for (OMPClause *C : Clauses) {
4616 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
4617 for (Expr *E : IRC->taskgroup_descriptors())
4618 if (E)
4619 ImplicitFirstprivates.emplace_back(E);
4620 }
4621 }
4622 if (!ImplicitFirstprivates.empty()) {
4623 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4624 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
4625 SourceLocation())) {
4626 ClausesWithImplicit.push_back(Implicit);
4627 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4628 ImplicitFirstprivates.size();
4629 } else {
4630 ErrorFound = true;
4631 }
4632 }
4633 int ClauseKindCnt = -1;
4634 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
4635 ++ClauseKindCnt;
4636 if (ImplicitMap.empty())
4637 continue;
4638 CXXScopeSpec MapperIdScopeSpec;
4639 DeclarationNameInfo MapperId;
4640 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
4641 if (OMPClause *Implicit = ActOnOpenMPMapClause(
4642 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
4643 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
4644 ImplicitMap, OMPVarListLocTy())) {
4645 ClausesWithImplicit.emplace_back(Implicit);
4646 ErrorFound |=
4647 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
4648 } else {
4649 ErrorFound = true;
4650 }
4651 }
4652 }
4653
4654 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
4655 switch (Kind) {
4656 case OMPD_parallel:
4657 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4658 EndLoc);
4659 AllowedNameModifiers.push_back(OMPD_parallel);
4660 break;
4661 case OMPD_simd:
4662 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4663 VarsWithInheritedDSA);
4664 if (LangOpts.OpenMP >= 50)
4665 AllowedNameModifiers.push_back(OMPD_simd);
4666 break;
4667 case OMPD_for:
4668 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4669 VarsWithInheritedDSA);
4670 break;
4671 case OMPD_for_simd:
4672 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4673 EndLoc, VarsWithInheritedDSA);
4674 if (LangOpts.OpenMP >= 50)
4675 AllowedNameModifiers.push_back(OMPD_simd);
4676 break;
4677 case OMPD_sections:
4678 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4679 EndLoc);
4680 break;
4681 case OMPD_section:
4682 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4683, __PRETTY_FUNCTION__))
4683 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4683, __PRETTY_FUNCTION__))
;
4684 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4685 break;
4686 case OMPD_single:
4687 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4688 EndLoc);
4689 break;
4690 case OMPD_master:
4691 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4692, __PRETTY_FUNCTION__))
4692 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4692, __PRETTY_FUNCTION__))
;
4693 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4694 break;
4695 case OMPD_critical:
4696 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4697 StartLoc, EndLoc);
4698 break;
4699 case OMPD_parallel_for:
4700 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4701 EndLoc, VarsWithInheritedDSA);
4702 AllowedNameModifiers.push_back(OMPD_parallel);
4703 break;
4704 case OMPD_parallel_for_simd:
4705 Res = ActOnOpenMPParallelForSimdDirective(
4706 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4707 AllowedNameModifiers.push_back(OMPD_parallel);
4708 if (LangOpts.OpenMP >= 50)
4709 AllowedNameModifiers.push_back(OMPD_simd);
4710 break;
4711 case OMPD_parallel_master:
4712 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
4713 StartLoc, EndLoc);
4714 AllowedNameModifiers.push_back(OMPD_parallel);
4715 break;
4716 case OMPD_parallel_sections:
4717 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4718 StartLoc, EndLoc);
4719 AllowedNameModifiers.push_back(OMPD_parallel);
4720 break;
4721 case OMPD_task:
4722 Res =
4723 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4724 AllowedNameModifiers.push_back(OMPD_task);
4725 break;
4726 case OMPD_taskyield:
4727 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4728, __PRETTY_FUNCTION__))
4728 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4728, __PRETTY_FUNCTION__))
;
4729 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4730, __PRETTY_FUNCTION__))
4730 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4730, __PRETTY_FUNCTION__))
;
4731 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4732 break;
4733 case OMPD_barrier:
4734 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4735, __PRETTY_FUNCTION__))
4735 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4735, __PRETTY_FUNCTION__))
;
4736 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4737, __PRETTY_FUNCTION__))
4737 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4737, __PRETTY_FUNCTION__))
;
4738 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4739 break;
4740 case OMPD_taskwait:
4741 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4742, __PRETTY_FUNCTION__))
4742 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4742, __PRETTY_FUNCTION__))
;
4743 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4744, __PRETTY_FUNCTION__))
4744 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4744, __PRETTY_FUNCTION__))
;
4745 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4746 break;
4747 case OMPD_taskgroup:
4748 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4749 EndLoc);
4750 break;
4751 case OMPD_flush:
4752 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4753, __PRETTY_FUNCTION__))
4753 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4753, __PRETTY_FUNCTION__))
;
4754 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4755 break;
4756 case OMPD_depobj:
4757 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4758, __PRETTY_FUNCTION__))
4758 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4758, __PRETTY_FUNCTION__))
;
4759 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
4760 break;
4761 case OMPD_ordered:
4762 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4763 EndLoc);
4764 break;
4765 case OMPD_atomic:
4766 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4767 EndLoc);
4768 break;
4769 case OMPD_teams:
4770 Res =
4771 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4772 break;
4773 case OMPD_target:
4774 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4775 EndLoc);
4776 AllowedNameModifiers.push_back(OMPD_target);
4777 break;
4778 case OMPD_target_parallel:
4779 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4780 StartLoc, EndLoc);
4781 AllowedNameModifiers.push_back(OMPD_target);
4782 AllowedNameModifiers.push_back(OMPD_parallel);
4783 break;
4784 case OMPD_target_parallel_for:
4785 Res = ActOnOpenMPTargetParallelForDirective(
4786 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4787 AllowedNameModifiers.push_back(OMPD_target);
4788 AllowedNameModifiers.push_back(OMPD_parallel);
4789 break;
4790 case OMPD_cancellation_point:
4791 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4792, __PRETTY_FUNCTION__))
4792 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4792, __PRETTY_FUNCTION__))
;
4793 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4794, __PRETTY_FUNCTION__))
4794 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4794, __PRETTY_FUNCTION__))
;
4795 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4796 break;
4797 case OMPD_cancel:
4798 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4799, __PRETTY_FUNCTION__))
4799 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4799, __PRETTY_FUNCTION__))
;
4800 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4801 CancelRegion);
4802 AllowedNameModifiers.push_back(OMPD_cancel);
4803 break;
4804 case OMPD_target_data:
4805 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4806 EndLoc);
4807 AllowedNameModifiers.push_back(OMPD_target_data);
4808 break;
4809 case OMPD_target_enter_data:
4810 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4811 EndLoc, AStmt);
4812 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4813 break;
4814 case OMPD_target_exit_data:
4815 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4816 EndLoc, AStmt);
4817 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4818 break;
4819 case OMPD_taskloop:
4820 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4821 EndLoc, VarsWithInheritedDSA);
4822 AllowedNameModifiers.push_back(OMPD_taskloop);
4823 break;
4824 case OMPD_taskloop_simd:
4825 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4826 EndLoc, VarsWithInheritedDSA);
4827 AllowedNameModifiers.push_back(OMPD_taskloop);
4828 if (LangOpts.OpenMP >= 50)
4829 AllowedNameModifiers.push_back(OMPD_simd);
4830 break;
4831 case OMPD_master_taskloop:
4832 Res = ActOnOpenMPMasterTaskLoopDirective(
4833 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4834 AllowedNameModifiers.push_back(OMPD_taskloop);
4835 break;
4836 case OMPD_master_taskloop_simd:
4837 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4838 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4839 AllowedNameModifiers.push_back(OMPD_taskloop);
4840 if (LangOpts.OpenMP >= 50)
4841 AllowedNameModifiers.push_back(OMPD_simd);
4842 break;
4843 case OMPD_parallel_master_taskloop:
4844 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4845 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4846 AllowedNameModifiers.push_back(OMPD_taskloop);
4847 AllowedNameModifiers.push_back(OMPD_parallel);
4848 break;
4849 case OMPD_parallel_master_taskloop_simd:
4850 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
4851 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4852 AllowedNameModifiers.push_back(OMPD_taskloop);
4853 AllowedNameModifiers.push_back(OMPD_parallel);
4854 if (LangOpts.OpenMP >= 50)
4855 AllowedNameModifiers.push_back(OMPD_simd);
4856 break;
4857 case OMPD_distribute:
4858 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4859 EndLoc, VarsWithInheritedDSA);
4860 break;
4861 case OMPD_target_update:
4862 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4863 EndLoc, AStmt);
4864 AllowedNameModifiers.push_back(OMPD_target_update);
4865 break;
4866 case OMPD_distribute_parallel_for:
4867 Res = ActOnOpenMPDistributeParallelForDirective(
4868 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4869 AllowedNameModifiers.push_back(OMPD_parallel);
4870 break;
4871 case OMPD_distribute_parallel_for_simd:
4872 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4873 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4874 AllowedNameModifiers.push_back(OMPD_parallel);
4875 if (LangOpts.OpenMP >= 50)
4876 AllowedNameModifiers.push_back(OMPD_simd);
4877 break;
4878 case OMPD_distribute_simd:
4879 Res = ActOnOpenMPDistributeSimdDirective(
4880 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4881 if (LangOpts.OpenMP >= 50)
4882 AllowedNameModifiers.push_back(OMPD_simd);
4883 break;
4884 case OMPD_target_parallel_for_simd:
4885 Res = ActOnOpenMPTargetParallelForSimdDirective(
4886 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4887 AllowedNameModifiers.push_back(OMPD_target);
4888 AllowedNameModifiers.push_back(OMPD_parallel);
4889 if (LangOpts.OpenMP >= 50)
4890 AllowedNameModifiers.push_back(OMPD_simd);
4891 break;
4892 case OMPD_target_simd:
4893 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4894 EndLoc, VarsWithInheritedDSA);
4895 AllowedNameModifiers.push_back(OMPD_target);
4896 if (LangOpts.OpenMP >= 50)
4897 AllowedNameModifiers.push_back(OMPD_simd);
4898 break;
4899 case OMPD_teams_distribute:
4900 Res = ActOnOpenMPTeamsDistributeDirective(
4901 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4902 break;
4903 case OMPD_teams_distribute_simd:
4904 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4905 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4906 if (LangOpts.OpenMP >= 50)
4907 AllowedNameModifiers.push_back(OMPD_simd);
4908 break;
4909 case OMPD_teams_distribute_parallel_for_simd:
4910 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4911 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4912 AllowedNameModifiers.push_back(OMPD_parallel);
4913 if (LangOpts.OpenMP >= 50)
4914 AllowedNameModifiers.push_back(OMPD_simd);
4915 break;
4916 case OMPD_teams_distribute_parallel_for:
4917 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4918 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4919 AllowedNameModifiers.push_back(OMPD_parallel);
4920 break;
4921 case OMPD_target_teams:
4922 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4923 EndLoc);
4924 AllowedNameModifiers.push_back(OMPD_target);
4925 break;
4926 case OMPD_target_teams_distribute:
4927 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4928 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4929 AllowedNameModifiers.push_back(OMPD_target);
4930 break;
4931 case OMPD_target_teams_distribute_parallel_for:
4932 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4933 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4934 AllowedNameModifiers.push_back(OMPD_target);
4935 AllowedNameModifiers.push_back(OMPD_parallel);
4936 break;
4937 case OMPD_target_teams_distribute_parallel_for_simd:
4938 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4939 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4940 AllowedNameModifiers.push_back(OMPD_target);
4941 AllowedNameModifiers.push_back(OMPD_parallel);
4942 if (LangOpts.OpenMP >= 50)
4943 AllowedNameModifiers.push_back(OMPD_simd);
4944 break;
4945 case OMPD_target_teams_distribute_simd:
4946 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4947 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4948 AllowedNameModifiers.push_back(OMPD_target);
4949 if (LangOpts.OpenMP >= 50)
4950 AllowedNameModifiers.push_back(OMPD_simd);
4951 break;
4952 case OMPD_declare_target:
4953 case OMPD_end_declare_target:
4954 case OMPD_threadprivate:
4955 case OMPD_allocate:
4956 case OMPD_declare_reduction:
4957 case OMPD_declare_mapper:
4958 case OMPD_declare_simd:
4959 case OMPD_requires:
4960 case OMPD_declare_variant:
4961 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4961)
;
4962 case OMPD_unknown:
4963 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 4963)
;
4964 }
4965
4966 ErrorFound = Res.isInvalid() || ErrorFound;
4967
4968 // Check variables in the clauses if default(none) was specified.
4969 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none) {
4970 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, nullptr);
4971 for (OMPClause *C : Clauses) {
4972 switch (C->getClauseKind()) {
4973 case OMPC_num_threads:
4974 case OMPC_dist_schedule:
4975 // Do not analyse if no parent teams directive.
4976 if (isOpenMPTeamsDirective(Kind))
4977 break;
4978 continue;
4979 case OMPC_if:
4980 if (isOpenMPTeamsDirective(Kind) &&
4981 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4982 break;
4983 if (isOpenMPParallelDirective(Kind) &&
4984 isOpenMPTaskLoopDirective(Kind) &&
4985 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
4986 break;
4987 continue;
4988 case OMPC_schedule:
4989 break;
4990 case OMPC_grainsize:
4991 case OMPC_num_tasks:
4992 case OMPC_final:
4993 case OMPC_priority:
4994 // Do not analyze if no parent parallel directive.
4995 if (isOpenMPParallelDirective(Kind))
4996 break;
4997 continue;
4998 case OMPC_ordered:
4999 case OMPC_device:
5000 case OMPC_num_teams:
5001 case OMPC_thread_limit:
5002 case OMPC_hint:
5003 case OMPC_collapse:
5004 case OMPC_safelen:
5005 case OMPC_simdlen:
5006 case OMPC_default:
5007 case OMPC_proc_bind:
5008 case OMPC_private:
5009 case OMPC_firstprivate:
5010 case OMPC_lastprivate:
5011 case OMPC_shared:
5012 case OMPC_reduction:
5013 case OMPC_task_reduction:
5014 case OMPC_in_reduction:
5015 case OMPC_linear:
5016 case OMPC_aligned:
5017 case OMPC_copyin:
5018 case OMPC_copyprivate:
5019 case OMPC_nowait:
5020 case OMPC_untied:
5021 case OMPC_mergeable:
5022 case OMPC_allocate:
5023 case OMPC_read:
5024 case OMPC_write:
5025 case OMPC_update:
5026 case OMPC_capture:
5027 case OMPC_seq_cst:
5028 case OMPC_acq_rel:
5029 case OMPC_acquire:
5030 case OMPC_release:
5031 case OMPC_relaxed:
5032 case OMPC_depend:
5033 case OMPC_threads:
5034 case OMPC_simd:
5035 case OMPC_map:
5036 case OMPC_nogroup:
5037 case OMPC_defaultmap:
5038 case OMPC_to:
5039 case OMPC_from:
5040 case OMPC_use_device_ptr:
5041 case OMPC_is_device_ptr:
5042 case OMPC_nontemporal:
5043 case OMPC_order:
5044 case OMPC_destroy:
5045 continue;
5046 case OMPC_allocator:
5047 case OMPC_flush:
5048 case OMPC_depobj:
5049 case OMPC_threadprivate:
5050 case OMPC_uniform:
5051 case OMPC_unknown:
5052 case OMPC_unified_address:
5053 case OMPC_unified_shared_memory:
5054 case OMPC_reverse_offload:
5055 case OMPC_dynamic_allocators:
5056 case OMPC_atomic_default_mem_order:
5057 case OMPC_device_type:
5058 case OMPC_match:
5059 llvm_unreachable("Unexpected clause")::llvm::llvm_unreachable_internal("Unexpected clause", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5059)
;
5060 }
5061 for (Stmt *CC : C->children()) {
5062 if (CC)
5063 DSAChecker.Visit(CC);
5064 }
5065 }
5066 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5067 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5068 }
5069 for (const auto &P : VarsWithInheritedDSA) {
5070 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5071 continue;
5072 ErrorFound = true;
5073 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSA() == DSA_none) {
5074 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5075 << P.first << P.second->getSourceRange();
5076 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5077 } else if (getLangOpts().OpenMP >= 50) {
5078 Diag(P.second->getExprLoc(),
5079 diag::err_omp_defaultmap_no_attr_for_variable)
5080 << P.first << P.second->getSourceRange();
5081 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDSALocation(),
5082 diag::note_omp_defaultmap_attr_none);
5083 }
5084 }
5085
5086 if (!AllowedNameModifiers.empty())
5087 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5088 ErrorFound;
5089
5090 if (ErrorFound)
5091 return StmtError();
5092
5093 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) {
5094 Res.getAs<OMPExecutableDirective>()
5095 ->getStructuredBlock()
5096 ->setIsOMPStructuredBlock(true);
5097 }
5098
5099 if (!CurContext->isDependentContext() &&
5100 isOpenMPTargetExecutionDirective(Kind) &&
5101 !(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5102 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5104 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5105 // Register target to DSA Stack.
5106 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addTargetDirLocation(StartLoc);
5107 }
5108
5109 return Res;
5110}
5111
5112Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5113 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5114 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5115 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5116 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5117 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5117, __PRETTY_FUNCTION__))
;
5118 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5118, __PRETTY_FUNCTION__))
;
5119 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5119, __PRETTY_FUNCTION__))
;
5120 if (!DG || DG.get().isNull())
5121 return DeclGroupPtrTy();
5122
5123 const int SimdId = 0;
5124 if (!DG.get().isSingleDecl()) {
5125 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5126 << SimdId;
5127 return DG;
5128 }
5129 Decl *ADecl = DG.get().getSingleDecl();
5130 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5131 ADecl = FTD->getTemplatedDecl();
5132
5133 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5134 if (!FD) {
5135 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5136 return DeclGroupPtrTy();
5137 }
5138
5139 // OpenMP [2.8.2, declare simd construct, Description]
5140 // The parameter of the simdlen clause must be a constant positive integer
5141 // expression.
5142 ExprResult SL;
5143 if (Simdlen)
5144 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5145 // OpenMP [2.8.2, declare simd construct, Description]
5146 // The special this pointer can be used as if was one of the arguments to the
5147 // function in any of the linear, aligned, or uniform clauses.
5148 // The uniform clause declares one or more arguments to have an invariant
5149 // value for all concurrent invocations of the function in the execution of a
5150 // single SIMD loop.
5151 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5152 const Expr *UniformedLinearThis = nullptr;
5153 for (const Expr *E : Uniforms) {
5154 E = E->IgnoreParenImpCasts();
5155 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5156 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5157 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5158 FD->getParamDecl(PVD->getFunctionScopeIndex())
5159 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5160 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5161 continue;
5162 }
5163 if (isa<CXXThisExpr>(E)) {
5164 UniformedLinearThis = E;
5165 continue;
5166 }
5167 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5168 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5169 }
5170 // OpenMP [2.8.2, declare simd construct, Description]
5171 // The aligned clause declares that the object to which each list item points
5172 // is aligned to the number of bytes expressed in the optional parameter of
5173 // the aligned clause.
5174 // The special this pointer can be used as if was one of the arguments to the
5175 // function in any of the linear, aligned, or uniform clauses.
5176 // The type of list items appearing in the aligned clause must be array,
5177 // pointer, reference to array, or reference to pointer.
5178 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5179 const Expr *AlignedThis = nullptr;
5180 for (const Expr *E : Aligneds) {
5181 E = E->IgnoreParenImpCasts();
5182 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5183 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5184 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5185 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5186 FD->getParamDecl(PVD->getFunctionScopeIndex())
5187 ->getCanonicalDecl() == CanonPVD) {
5188 // OpenMP [2.8.1, simd construct, Restrictions]
5189 // A list-item cannot appear in more than one aligned clause.
5190 if (AlignedArgs.count(CanonPVD) > 0) {
5191 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5192 << 1 << getOpenMPClauseName(OMPC_aligned)
5193 << E->getSourceRange();
5194 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5195 diag::note_omp_explicit_dsa)
5196 << getOpenMPClauseName(OMPC_aligned);
5197 continue;
5198 }
5199 AlignedArgs[CanonPVD] = E;
5200 QualType QTy = PVD->getType()
5201 .getNonReferenceType()
5202 .getUnqualifiedType()
5203 .getCanonicalType();
5204 const Type *Ty = QTy.getTypePtrOrNull();
5205 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5206 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5207 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5208 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5209 }
5210 continue;
5211 }
5212 }
5213 if (isa<CXXThisExpr>(E)) {
5214 if (AlignedThis) {
5215 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5216 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5217 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5218 << getOpenMPClauseName(OMPC_aligned);
5219 }
5220 AlignedThis = E;
5221 continue;
5222 }
5223 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5224 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5225 }
5226 // The optional parameter of the aligned clause, alignment, must be a constant
5227 // positive integer expression. If no optional parameter is specified,
5228 // implementation-defined default alignments for SIMD instructions on the
5229 // target platforms are assumed.
5230 SmallVector<const Expr *, 4> NewAligns;
5231 for (Expr *E : Alignments) {
5232 ExprResult Align;
5233 if (E)
5234 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5235 NewAligns.push_back(Align.get());
5236 }
5237 // OpenMP [2.8.2, declare simd construct, Description]
5238 // The linear clause declares one or more list items to be private to a SIMD
5239 // lane and to have a linear relationship with respect to the iteration space
5240 // of a loop.
5241 // The special this pointer can be used as if was one of the arguments to the
5242 // function in any of the linear, aligned, or uniform clauses.
5243 // When a linear-step expression is specified in a linear clause it must be
5244 // either a constant integer expression or an integer-typed parameter that is
5245 // specified in a uniform clause on the directive.
5246 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5247 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5248 auto MI = LinModifiers.begin();
5249 for (const Expr *E : Linears) {
5250 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5251 ++MI;
5252 E = E->IgnoreParenImpCasts();
5253 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5254 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5255 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5256 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5257 FD->getParamDecl(PVD->getFunctionScopeIndex())
5258 ->getCanonicalDecl() == CanonPVD) {
5259 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5260 // A list-item cannot appear in more than one linear clause.
5261 if (LinearArgs.count(CanonPVD) > 0) {
5262 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5263 << getOpenMPClauseName(OMPC_linear)
5264 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5265 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5266 diag::note_omp_explicit_dsa)
5267 << getOpenMPClauseName(OMPC_linear);
5268 continue;
5269 }
5270 // Each argument can appear in at most one uniform or linear clause.
5271 if (UniformedArgs.count(CanonPVD) > 0) {
5272 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5273 << getOpenMPClauseName(OMPC_linear)
5274 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5275 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5276 diag::note_omp_explicit_dsa)
5277 << getOpenMPClauseName(OMPC_uniform);
5278 continue;
5279 }
5280 LinearArgs[CanonPVD] = E;
5281 if (E->isValueDependent() || E->isTypeDependent() ||
5282 E->isInstantiationDependent() ||
5283 E->containsUnexpandedParameterPack())
5284 continue;
5285 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5286 PVD->getOriginalType(),
5287 /*IsDeclareSimd=*/true);
5288 continue;
5289 }
5290 }
5291 if (isa<CXXThisExpr>(E)) {
5292 if (UniformedLinearThis) {
5293 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5294 << getOpenMPClauseName(OMPC_linear)
5295 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5296 << E->getSourceRange();
5297 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5298 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5299 : OMPC_linear);
5300 continue;
5301 }
5302 UniformedLinearThis = E;
5303 if (E->isValueDependent() || E->isTypeDependent() ||
5304 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5305 continue;
5306 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5307 E->getType(), /*IsDeclareSimd=*/true);
5308 continue;
5309 }
5310 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5311 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5312 }
5313 Expr *Step = nullptr;
5314 Expr *NewStep = nullptr;
5315 SmallVector<Expr *, 4> NewSteps;
5316 for (Expr *E : Steps) {
5317 // Skip the same step expression, it was checked already.
5318 if (Step == E || !E) {
5319 NewSteps.push_back(E ? NewStep : nullptr);
5320 continue;
5321 }
5322 Step = E;
5323 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5324 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5325 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5326 if (UniformedArgs.count(CanonPVD) == 0) {
5327 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5328 << Step->getSourceRange();
5329 } else if (E->isValueDependent() || E->isTypeDependent() ||
5330 E->isInstantiationDependent() ||
5331 E->containsUnexpandedParameterPack() ||
5332 CanonPVD->getType()->hasIntegerRepresentation()) {
5333 NewSteps.push_back(Step);
5334 } else {
5335 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5336 << Step->getSourceRange();
5337 }
5338 continue;
5339 }
5340 NewStep = Step;
5341 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5342 !Step->isInstantiationDependent() &&
5343 !Step->containsUnexpandedParameterPack()) {
5344 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5345 .get();
5346 if (NewStep)
5347 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5348 }
5349 NewSteps.push_back(NewStep);
5350 }
5351 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5352 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5353 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5354 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5355 const_cast<Expr **>(Linears.data()), Linears.size(),
5356 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5357 NewSteps.data(), NewSteps.size(), SR);
5358 ADecl->addAttr(NewAttr);
5359 return DG;
5360}
5361
5362static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5363 QualType NewType) {
5364 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5365, __PRETTY_FUNCTION__))
5365 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5365, __PRETTY_FUNCTION__))
;
5366 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5367, __PRETTY_FUNCTION__))
5367 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5367, __PRETTY_FUNCTION__))
;
5368 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5369, __PRETTY_FUNCTION__))
5369 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5369, __PRETTY_FUNCTION__))
;
5370 // Synthesize parameters with the same types.
5371 FD->setType(NewType);
5372 SmallVector<ParmVarDecl *, 16> Params;
5373 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5374 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5375 SourceLocation(), nullptr, P->getType(),
5376 /*TInfo=*/nullptr, SC_None, nullptr);
5377 Param->setScopeInfo(0, Params.size());
5378 Param->setImplicit();
5379 Params.push_back(Param);
5380 }
5381
5382 FD->setParams(Params);
5383}
5384
5385Optional<std::pair<FunctionDecl *, Expr *>>
5386Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
5387 Expr *VariantRef, OMPTraitInfo &TI,
5388 SourceRange SR) {
5389 if (!DG || DG.get().isNull())
5390 return None;
5391
5392 const int VariantId = 1;
5393 // Must be applied only to single decl.
5394 if (!DG.get().isSingleDecl()) {
5395 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5396 << VariantId << SR;
5397 return None;
5398 }
5399 Decl *ADecl = DG.get().getSingleDecl();
5400 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5401 ADecl = FTD->getTemplatedDecl();
5402
5403 // Decl must be a function.
5404 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5405 if (!FD) {
5406 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5407 << VariantId << SR;
5408 return None;
5409 }
5410
5411 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
5412 return FD->hasAttrs() &&
5413 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5414 FD->hasAttr<TargetAttr>());
5415 };
5416 // OpenMP is not compatible with CPU-specific attributes.
5417 if (HasMultiVersionAttributes(FD)) {
5418 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
5419 << SR;
5420 return None;
5421 }
5422
5423 // Allow #pragma omp declare variant only if the function is not used.
5424 if (FD->isUsed(false))
5425 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
5426 << FD->getLocation();
5427
5428 // Check if the function was emitted already.
5429 const FunctionDecl *Definition;
5430 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5431 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
5432 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
5433 << FD->getLocation();
5434
5435 // The VariantRef must point to function.
5436 if (!VariantRef) {
5437 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
5438 return None;
5439 }
5440
5441 auto ShouldDelayChecks = [](Expr *&E, bool) {
5442 return E && (E->isTypeDependent() || E->isValueDependent() ||
5443 E->containsUnexpandedParameterPack() ||
5444 E->isInstantiationDependent());
5445 };
5446 // Do not check templates, wait until instantiation.
5447 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
5448 TI.anyScoreOrCondition(ShouldDelayChecks))
5449 return std::make_pair(FD, VariantRef);
5450
5451 // Deal with non-constant score and user condition expressions.
5452 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
5453 bool IsScore) -> bool {
5454 llvm::APSInt Result;
5455 if (!E || E->isIntegerConstantExpr(Result, Context))
5456 return false;
5457
5458 if (IsScore) {
5459 // We warn on non-constant scores and pretend they were not present.
5460 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
5461 << E;
5462 E = nullptr;
5463 } else {
5464 // We could replace a non-constant user condition with "false" but we
5465 // will soon need to handle these anyway for the dynamic version of
5466 // OpenMP context selectors.
5467 Diag(E->getExprLoc(),
5468 diag::err_omp_declare_variant_user_condition_not_constant)
5469 << E;
5470 }
5471 return true;
5472 };
5473 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
5474 return None;
5475
5476 // Convert VariantRef expression to the type of the original function to
5477 // resolve possible conflicts.
5478 ExprResult VariantRefCast;
5479 if (LangOpts.CPlusPlus) {
5480 QualType FnPtrType;
5481 auto *Method = dyn_cast<CXXMethodDecl>(FD);
5482 if (Method && !Method->isStatic()) {
5483 const Type *ClassType =
5484 Context.getTypeDeclType(Method->getParent()).getTypePtr();
5485 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
5486 ExprResult ER;
5487 {
5488 // Build adrr_of unary op to correctly handle type checks for member
5489 // functions.
5490 Sema::TentativeAnalysisScope Trap(*this);
5491 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
5492 VariantRef);
5493 }
5494 if (!ER.isUsable()) {
5495 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5496 << VariantId << VariantRef->getSourceRange();
5497 return None;
5498 }
5499 VariantRef = ER.get();
5500 } else {
5501 FnPtrType = Context.getPointerType(FD->getType());
5502 }
5503 ImplicitConversionSequence ICS =
5504 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
5505 /*SuppressUserConversions=*/false,
5506 AllowedExplicit::None,
5507 /*InOverloadResolution=*/false,
5508 /*CStyle=*/false,
5509 /*AllowObjCWritebackConversion=*/false);
5510 if (ICS.isFailure()) {
5511 Diag(VariantRef->getExprLoc(),
5512 diag::err_omp_declare_variant_incompat_types)
5513 << VariantRef->getType()
5514 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
5515 << VariantRef->getSourceRange();
5516 return None;
5517 }
5518 VariantRefCast = PerformImplicitConversion(
5519 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
5520 if (!VariantRefCast.isUsable())
5521 return None;
5522 // Drop previously built artificial addr_of unary op for member functions.
5523 if (Method && !Method->isStatic()) {
5524 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
5525 if (auto *UO = dyn_cast<UnaryOperator>(
5526 PossibleAddrOfVariantRef->IgnoreImplicit()))
5527 VariantRefCast = UO->getSubExpr();
5528 }
5529 } else {
5530 VariantRefCast = VariantRef;
5531 }
5532
5533 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
5534 if (!ER.isUsable() ||
5535 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5536 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5537 << VariantId << VariantRef->getSourceRange();
5538 return None;
5539 }
5540
5541 // The VariantRef must point to function.
5542 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
5543 if (!DRE) {
5544 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5545 << VariantId << VariantRef->getSourceRange();
5546 return None;
5547 }
5548 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5549 if (!NewFD) {
5550 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5551 << VariantId << VariantRef->getSourceRange();
5552 return None;
5553 }
5554
5555 // Check if function types are compatible in C.
5556 if (!LangOpts.CPlusPlus) {
5557 QualType NewType =
5558 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
5559 if (NewType.isNull()) {
5560 Diag(VariantRef->getExprLoc(),
5561 diag::err_omp_declare_variant_incompat_types)
5562 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
5563 return None;
5564 }
5565 if (NewType->isFunctionProtoType()) {
5566 if (FD->getType()->isFunctionNoProtoType())
5567 setPrototype(*this, FD, NewFD, NewType);
5568 else if (NewFD->getType()->isFunctionNoProtoType())
5569 setPrototype(*this, NewFD, FD, NewType);
5570 }
5571 }
5572
5573 // Check if variant function is not marked with declare variant directive.
5574 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5575 Diag(VariantRef->getExprLoc(),
5576 diag::warn_omp_declare_variant_marked_as_declare_variant)
5577 << VariantRef->getSourceRange();
5578 SourceRange SR =
5579 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5580 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
5581 return None;
5582 }
5583
5584 enum DoesntSupport {
5585 VirtFuncs = 1,
5586 Constructors = 3,
5587 Destructors = 4,
5588 DeletedFuncs = 5,
5589 DefaultedFuncs = 6,
5590 ConstexprFuncs = 7,
5591 ConstevalFuncs = 8,
5592 };
5593 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5594 if (CXXFD->isVirtual()) {
5595 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5596 << VirtFuncs;
5597 return None;
5598 }
5599
5600 if (isa<CXXConstructorDecl>(FD)) {
5601 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5602 << Constructors;
5603 return None;
5604 }
5605
5606 if (isa<CXXDestructorDecl>(FD)) {
5607 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5608 << Destructors;
5609 return None;
5610 }
5611 }
5612
5613 if (FD->isDeleted()) {
5614 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5615 << DeletedFuncs;
5616 return None;
5617 }
5618
5619 if (FD->isDefaulted()) {
5620 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5621 << DefaultedFuncs;
5622 return None;
5623 }
5624
5625 if (FD->isConstexpr()) {
5626 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5627 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
5628 return None;
5629 }
5630
5631 // Check general compatibility.
5632 if (areMultiversionVariantFunctionsCompatible(
5633 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
5634 PartialDiagnosticAt(SourceLocation(),
5635 PartialDiagnostic::NullDiagnostic()),
5636 PartialDiagnosticAt(
5637 VariantRef->getExprLoc(),
5638 PDiag(diag::err_omp_declare_variant_doesnt_support)),
5639 PartialDiagnosticAt(VariantRef->getExprLoc(),
5640 PDiag(diag::err_omp_declare_variant_diff)
5641 << FD->getLocation()),
5642 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
5643 /*CLinkageMayDiffer=*/true))
5644 return None;
5645 return std::make_pair(FD, cast<Expr>(DRE));
5646}
5647
5648void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
5649 Expr *VariantRef,
5650 OMPTraitInfo &TI,
5651 SourceRange SR) {
5652 auto *NewAttr =
5653 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, TI, SR);
5654 FD->addAttr(NewAttr);
5655}
5656
5657void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
5658 FunctionDecl *Func,
5659 bool MightBeOdrUse) {
5660 assert(LangOpts.OpenMP && "Expected OpenMP mode.")((LangOpts.OpenMP && "Expected OpenMP mode.") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"Expected OpenMP mode.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5660, __PRETTY_FUNCTION__))
;
5661
5662 if (!Func->isDependentContext() && Func->hasAttrs()) {
5663 for (OMPDeclareVariantAttr *A :
5664 Func->specific_attrs<OMPDeclareVariantAttr>()) {
5665 // TODO: add checks for active OpenMP context where possible.
5666 Expr *VariantRef = A->getVariantFuncRef();
5667 auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts());
5668 auto *F = cast<FunctionDecl>(DRE->getDecl());
5669 if (!F->isDefined() && F->isTemplateInstantiation())
5670 InstantiateFunctionDefinition(Loc, F->getFirstDecl());
5671 MarkFunctionReferenced(Loc, F, MightBeOdrUse);
5672 }
5673 }
5674}
5675
5676StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
5677 Stmt *AStmt,
5678 SourceLocation StartLoc,
5679 SourceLocation EndLoc) {
5680 if (!AStmt)
5681 return StmtError();
5682
5683 auto *CS = cast<CapturedStmt>(AStmt);
5684 // 1.2.2 OpenMP Language Terminology
5685 // Structured block - An executable statement with a single entry at the
5686 // top and a single exit at the bottom.
5687 // The point of exit cannot be a branch out of the structured block.
5688 // longjmp() and throw() must not violate the entry/exit criteria.
5689 CS->getCapturedDecl()->setNothrow();
5690
5691 setFunctionHasBranchProtectedScope();
5692
5693 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5694 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5695}
5696
5697namespace {
5698/// Iteration space of a single for loop.
5699struct LoopIterationSpace final {
5700 /// True if the condition operator is the strict compare operator (<, > or
5701 /// !=).
5702 bool IsStrictCompare = false;
5703 /// Condition of the loop.
5704 Expr *PreCond = nullptr;
5705 /// This expression calculates the number of iterations in the loop.
5706 /// It is always possible to calculate it before starting the loop.
5707 Expr *NumIterations = nullptr;
5708 /// The loop counter variable.
5709 Expr *CounterVar = nullptr;
5710 /// Private loop counter variable.
5711 Expr *PrivateCounterVar = nullptr;
5712 /// This is initializer for the initial value of #CounterVar.
5713 Expr *CounterInit = nullptr;
5714 /// This is step for the #CounterVar used to generate its update:
5715 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
5716 Expr *CounterStep = nullptr;
5717 /// Should step be subtracted?
5718 bool Subtract = false;
5719 /// Source range of the loop init.
5720 SourceRange InitSrcRange;
5721 /// Source range of the loop condition.
5722 SourceRange CondSrcRange;
5723 /// Source range of the loop increment.
5724 SourceRange IncSrcRange;
5725 /// Minimum value that can have the loop control variable. Used to support
5726 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
5727 /// since only such variables can be used in non-loop invariant expressions.
5728 Expr *MinValue = nullptr;
5729 /// Maximum value that can have the loop control variable. Used to support
5730 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
5731 /// since only such variables can be used in non-loop invariant expressions.
5732 Expr *MaxValue = nullptr;
5733 /// true, if the lower bound depends on the outer loop control var.
5734 bool IsNonRectangularLB = false;
5735 /// true, if the upper bound depends on the outer loop control var.
5736 bool IsNonRectangularUB = false;
5737 /// Index of the loop this loop depends on and forms non-rectangular loop
5738 /// nest.
5739 unsigned LoopDependentIdx = 0;
5740 /// Final condition for the non-rectangular loop nest support. It is used to
5741 /// check that the number of iterations for this particular counter must be
5742 /// finished.
5743 Expr *FinalCondition = nullptr;
5744};
5745
5746/// Helper class for checking canonical form of the OpenMP loops and
5747/// extracting iteration space of each loop in the loop nest, that will be used
5748/// for IR generation.
5749class OpenMPIterationSpaceChecker {
5750 /// Reference to Sema.
5751 Sema &SemaRef;
5752 /// Data-sharing stack.
5753 DSAStackTy &Stack;
5754 /// A location for diagnostics (when there is no some better location).
5755 SourceLocation DefaultLoc;
5756 /// A location for diagnostics (when increment is not compatible).
5757 SourceLocation ConditionLoc;
5758 /// A source location for referring to loop init later.
5759 SourceRange InitSrcRange;
5760 /// A source location for referring to condition later.
5761 SourceRange ConditionSrcRange;
5762 /// A source location for referring to increment later.
5763 SourceRange IncrementSrcRange;
5764 /// Loop variable.
5765 ValueDecl *LCDecl = nullptr;
5766 /// Reference to loop variable.
5767 Expr *LCRef = nullptr;
5768 /// Lower bound (initializer for the var).
5769 Expr *LB = nullptr;
13
Null pointer value stored to 'ISC.LB'
5770 /// Upper bound.
5771 Expr *UB = nullptr;
5772 /// Loop step (increment).
5773 Expr *Step = nullptr;
5774 /// This flag is true when condition is one of:
5775 /// Var < UB
5776 /// Var <= UB
5777 /// UB > Var
5778 /// UB >= Var
5779 /// This will have no value when the condition is !=
5780 llvm::Optional<bool> TestIsLessOp;
5781 /// This flag is true when condition is strict ( < or > ).
5782 bool TestIsStrictOp = false;
5783 /// This flag is true when step is subtracted on each iteration.
5784 bool SubtractStep = false;
5785 /// The outer loop counter this loop depends on (if any).
5786 const ValueDecl *DepDecl = nullptr;
5787 /// Contains number of loop (starts from 1) on which loop counter init
5788 /// expression of this loop depends on.
5789 Optional<unsigned> InitDependOnLC;
5790 /// Contains number of loop (starts from 1) on which loop counter condition
5791 /// expression of this loop depends on.
5792 Optional<unsigned> CondDependOnLC;
5793 /// Checks if the provide statement depends on the loop counter.
5794 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
5795 /// Original condition required for checking of the exit condition for
5796 /// non-rectangular loop.
5797 Expr *Condition = nullptr;
5798
5799public:
5800 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
5801 SourceLocation DefaultLoc)
5802 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
5803 ConditionLoc(DefaultLoc) {}
5804 /// Check init-expr for canonical loop form and save loop counter
5805 /// variable - #Var and its initialization value - #LB.
5806 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
5807 /// Check test-expr for canonical form, save upper-bound (#UB), flags
5808 /// for less/greater and for strict/non-strict comparison.
5809 bool checkAndSetCond(Expr *S);
5810 /// Check incr-expr for canonical loop form and return true if it
5811 /// does not conform, otherwise save loop step (#Step).
5812 bool checkAndSetInc(Expr *S);
5813 /// Return the loop counter variable.
5814 ValueDecl *getLoopDecl() const { return LCDecl; }
5815 /// Return the reference expression to loop counter variable.
5816 Expr *getLoopDeclRefExpr() const { return LCRef; }
5817 /// Source range of the loop init.
5818 SourceRange getInitSrcRange() const { return InitSrcRange; }
5819 /// Source range of the loop condition.
5820 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
5821 /// Source range of the loop increment.
5822 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
5823 /// True if the step should be subtracted.
5824 bool shouldSubtractStep() const { return SubtractStep; }
5825 /// True, if the compare operator is strict (<, > or !=).
5826 bool isStrictTestOp() const { return TestIsStrictOp; }
5827 /// Build the expression to calculate the number of iterations.
5828 Expr *buildNumIterations(
5829 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
5830 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5831 /// Build the precondition expression for the loops.
5832 Expr *
5833 buildPreCond(Scope *S, Expr *Cond,
5834 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5835 /// Build reference expression to the counter be used for codegen.
5836 DeclRefExpr *
5837 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5838 DSAStackTy &DSA) const;
5839 /// Build reference expression to the private counter be used for
5840 /// codegen.
5841 Expr *buildPrivateCounterVar() const;
5842 /// Build initialization of the counter be used for codegen.
5843 Expr *buildCounterInit() const;
5844 /// Build step of the counter be used for codegen.
5845 Expr *buildCounterStep() const;
5846 /// Build loop data with counter value for depend clauses in ordered
5847 /// directives.
5848 Expr *
5849 buildOrderedLoopData(Scope *S, Expr *Counter,
5850 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5851 SourceLocation Loc, Expr *Inc = nullptr,
5852 OverloadedOperatorKind OOK = OO_Amp);
5853 /// Builds the minimum value for the loop counter.
5854 std::pair<Expr *, Expr *> buildMinMaxValues(
5855 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5856 /// Builds final condition for the non-rectangular loops.
5857 Expr *buildFinalCondition(Scope *S) const;
5858 /// Return true if any expression is dependent.
5859 bool dependent() const;
5860 /// Returns true if the initializer forms non-rectangular loop.
5861 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
5862 /// Returns true if the condition forms non-rectangular loop.
5863 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
5864 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
5865 unsigned getLoopDependentIdx() const {
5866 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
5867 }
5868
5869private:
5870 /// Check the right-hand side of an assignment in the increment
5871 /// expression.
5872 bool checkAndSetIncRHS(Expr *RHS);
5873 /// Helper to set loop counter variable and its initializer.
5874 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
5875 bool EmitDiags);
5876 /// Helper to set upper bound.
5877 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
5878 SourceRange SR, SourceLocation SL);
5879 /// Helper to set loop increment.
5880 bool setStep(Expr *NewStep, bool Subtract);
5881};
5882
5883bool OpenMPIterationSpaceChecker::dependent() const {
5884 if (!LCDecl) {
5885 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5885, __PRETTY_FUNCTION__))
;
5886 return false;
5887 }
5888 return LCDecl->getType()->isDependentType() ||
5889 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
5890 (Step && Step->isValueDependent());
5891}
5892
5893bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
5894 Expr *NewLCRefExpr,
5895 Expr *NewLB, bool EmitDiags) {
5896 // State consistency checking to ensure correct usage.
5897 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5898, __PRETTY_FUNCTION__))
5898 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5898, __PRETTY_FUNCTION__))
;
5899 if (!NewLCDecl || !NewLB)
5900 return true;
5901 LCDecl = getCanonicalDecl(NewLCDecl);
5902 LCRef = NewLCRefExpr;
5903 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
5904 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
5905 if ((Ctor->isCopyOrMoveConstructor() ||
5906 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5907 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
5908 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
5909 LB = NewLB;
5910 if (EmitDiags)
5911 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
5912 return false;
5913}
5914
5915bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
5916 llvm::Optional<bool> LessOp,
5917 bool StrictOp, SourceRange SR,
5918 SourceLocation SL) {
5919 // State consistency checking to ensure correct usage.
5920 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5921, __PRETTY_FUNCTION__))
5921 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5921, __PRETTY_FUNCTION__))
;
5922 if (!NewUB)
5923 return true;
5924 UB = NewUB;
5925 if (LessOp)
5926 TestIsLessOp = LessOp;
5927 TestIsStrictOp = StrictOp;
5928 ConditionSrcRange = SR;
5929 ConditionLoc = SL;
5930 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
5931 return false;
5932}
5933
5934bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
5935 // State consistency checking to ensure correct usage.
5936 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 5936, __PRETTY_FUNCTION__))
;
5937 if (!NewStep)
5938 return true;
5939 if (!NewStep->isValueDependent()) {
5940 // Check that the step is integer expression.
5941 SourceLocation StepLoc = NewStep->getBeginLoc();
5942 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
5943 StepLoc, getExprAsWritten(NewStep));
5944 if (Val.isInvalid())
5945 return true;
5946 NewStep = Val.get();
5947
5948 // OpenMP [2.6, Canonical Loop Form, Restrictions]
5949 // If test-expr is of form var relational-op b and relational-op is < or
5950 // <= then incr-expr must cause var to increase on each iteration of the
5951 // loop. If test-expr is of form var relational-op b and relational-op is
5952 // > or >= then incr-expr must cause var to decrease on each iteration of
5953 // the loop.
5954 // If test-expr is of form b relational-op var and relational-op is < or
5955 // <= then incr-expr must cause var to decrease on each iteration of the
5956 // loop. If test-expr is of form b relational-op var and relational-op is
5957 // > or >= then incr-expr must cause var to increase on each iteration of
5958 // the loop.
5959 llvm::APSInt Result;
5960 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
5961 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
5962 bool IsConstNeg =
5963 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
5964 bool IsConstPos =
5965 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
5966 bool IsConstZero = IsConstant && !Result.getBoolValue();
5967
5968 // != with increment is treated as <; != with decrement is treated as >
5969 if (!TestIsLessOp.hasValue())
5970 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
5971 if (UB && (IsConstZero ||
5972 (TestIsLessOp.getValue() ?
5973 (IsConstNeg || (IsUnsigned && Subtract)) :
5974 (IsConstPos || (IsUnsigned && !Subtract))))) {
5975 SemaRef.Diag(NewStep->getExprLoc(),
5976 diag::err_omp_loop_incr_not_compatible)
5977 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
5978 SemaRef.Diag(ConditionLoc,
5979 diag::note_omp_loop_cond_requres_compatible_incr)
5980 << TestIsLessOp.getValue() << ConditionSrcRange;
5981 return true;
5982 }
5983 if (TestIsLessOp.getValue() == Subtract) {
5984 NewStep =
5985 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
5986 .get();
5987 Subtract = !Subtract;
5988 }
5989 }
5990
5991 Step = NewStep;
5992 SubtractStep = Subtract;
5993 return false;
5994}
5995
5996namespace {
5997/// Checker for the non-rectangular loops. Checks if the initializer or
5998/// condition expression references loop counter variable.
5999class LoopCounterRefChecker final
6000 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6001 Sema &SemaRef;
6002 DSAStackTy &Stack;
6003 const ValueDecl *CurLCDecl = nullptr;
6004 const ValueDecl *DepDecl = nullptr;
6005 const ValueDecl *PrevDepDecl = nullptr;
6006 bool IsInitializer = true;
6007 unsigned BaseLoopId = 0;
6008 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6009 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6010 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6011 << (IsInitializer ? 0 : 1);
6012 return false;
6013 }
6014 const auto &&Data = Stack.isLoopControlVariable(VD);
6015 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6016 // The type of the loop iterator on which we depend may not have a random
6017 // access iterator type.
6018 if (Data.first && VD->getType()->isRecordType()) {
6019 SmallString<128> Name;
6020 llvm::raw_svector_ostream OS(Name);
6021 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6022 /*Qualified=*/true);
6023 SemaRef.Diag(E->getExprLoc(),
6024 diag::err_omp_wrong_dependency_iterator_type)
6025 << OS.str();
6026 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6027 return false;
6028 }
6029 if (Data.first &&
6030 (DepDecl || (PrevDepDecl &&
6031 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6032 if (!DepDecl && PrevDepDecl)
6033 DepDecl = PrevDepDecl;
6034 SmallString<128> Name;
6035 llvm::raw_svector_ostream OS(Name);
6036 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6037 /*Qualified=*/true);
6038 SemaRef.Diag(E->getExprLoc(),
6039 diag::err_omp_invariant_or_linear_dependency)
6040 << OS.str();
6041 return false;
6042 }
6043 if (Data.first) {
6044 DepDecl = VD;
6045 BaseLoopId = Data.first;
6046 }
6047 return Data.first;
6048 }
6049
6050public:
6051 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6052 const ValueDecl *VD = E->getDecl();
6053 if (isa<VarDecl>(VD))
6054 return checkDecl(E, VD);
6055 return false;
6056 }
6057 bool VisitMemberExpr(const MemberExpr *E) {
6058 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6059 const ValueDecl *VD = E->getMemberDecl();
6060 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6061 return checkDecl(E, VD);
6062 }
6063 return false;
6064 }
6065 bool VisitStmt(const Stmt *S) {
6066 bool Res = false;
6067 for (const Stmt *Child : S->children())
6068 Res = (Child && Visit(Child)) || Res;
6069 return Res;
6070 }
6071 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6072 const ValueDecl *CurLCDecl, bool IsInitializer,
6073 const ValueDecl *PrevDepDecl = nullptr)
6074 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6075 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6076 unsigned getBaseLoopId() const {
6077 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6077, __PRETTY_FUNCTION__))
;
6078 return BaseLoopId;
6079 }
6080 const ValueDecl *getDepDecl() const {
6081 assert(CurLCDecl && "Expected loop dependency.")((CurLCDecl && "Expected loop dependency.") ? static_cast
<void> (0) : __assert_fail ("CurLCDecl && \"Expected loop dependency.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6081, __PRETTY_FUNCTION__))
;
6082 return DepDecl;
6083 }
6084};
6085} // namespace
6086
6087Optional<unsigned>
6088OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6089 bool IsInitializer) {
6090 // Check for the non-rectangular loops.
6091 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6092 DepDecl);
6093 if (LoopStmtChecker.Visit(S)) {
6094 DepDecl = LoopStmtChecker.getDepDecl();
6095 return LoopStmtChecker.getBaseLoopId();
6096 }
6097 return llvm::None;
6098}
6099
6100bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6101 // Check init-expr for canonical loop form and save loop counter
6102 // variable - #Var and its initialization value - #LB.
6103 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6104 // var = lb
6105 // integer-type var = lb
6106 // random-access-iterator-type var = lb
6107 // pointer-type var = lb
6108 //
6109 if (!S) {
6110 if (EmitDiags) {
6111 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6112 }
6113 return true;
6114 }
6115 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6116 if (!ExprTemp->cleanupsHaveSideEffects())
6117 S = ExprTemp->getSubExpr();
6118
6119 InitSrcRange = S->getSourceRange();
6120 if (Expr *E = dyn_cast<Expr>(S))
6121 S = E->IgnoreParens();
6122 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6123 if (BO->getOpcode() == BO_Assign) {
6124 Expr *LHS = BO->getLHS()->IgnoreParens();
6125 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6126 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6127 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6128 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6129 EmitDiags);
6130 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6131 }
6132 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6133 if (ME->isArrow() &&
6134 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6135 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6136 EmitDiags);
6137 }
6138 }
6139 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6140 if (DS->isSingleDecl()) {
6141 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6142 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6143 // Accept non-canonical init form here but emit ext. warning.
6144 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6145 SemaRef.Diag(S->getBeginLoc(),
6146 diag::ext_omp_loop_not_canonical_init)
6147 << S->getSourceRange();
6148 return setLCDeclAndLB(
6149 Var,
6150 buildDeclRefExpr(SemaRef, Var,
6151 Var->getType().getNonReferenceType(),
6152 DS->getBeginLoc()),
6153 Var->getInit(), EmitDiags);
6154 }
6155 }
6156 }
6157 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6158 if (CE->getOperator() == OO_Equal) {
6159 Expr *LHS = CE->getArg(0);
6160 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6161 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6162 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6163 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6164 EmitDiags);
6165 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6166 }
6167 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6168 if (ME->isArrow() &&
6169 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6170 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6171 EmitDiags);
6172 }
6173 }
6174 }
6175
6176 if (dependent() || SemaRef.CurContext->isDependentContext())
6177 return false;
6178 if (EmitDiags) {
6179 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6180 << S->getSourceRange();
6181 }
6182 return true;
6183}
6184
6185/// Ignore parenthesizes, implicit casts, copy constructor and return the
6186/// variable (which may be the loop variable) if possible.
6187static const ValueDecl *getInitLCDecl(const Expr *E) {
6188 if (!E)
6189 return nullptr;
6190 E = getExprAsWritten(E);
6191 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6192 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6193 if ((Ctor->isCopyOrMoveConstructor() ||
6194 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6195 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6196 E = CE->getArg(0)->IgnoreParenImpCasts();
6197 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6198 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6199 return getCanonicalDecl(VD);
6200 }
6201 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6202 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6203 return getCanonicalDecl(ME->getMemberDecl());
6204 return nullptr;
6205}
6206
6207bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6208 // Check test-expr for canonical form, save upper-bound UB, flags for
6209 // less/greater and for strict/non-strict comparison.
6210 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6211 // var relational-op b
6212 // b relational-op var
6213 //
6214 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6215 if (!S) {
6216 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6217 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6218 return true;
6219 }
6220 Condition = S;
6221 S = getExprAsWritten(S);
6222 SourceLocation CondLoc = S->getBeginLoc();
6223 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6224 if (BO->isRelationalOp()) {
6225 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6226 return setUB(BO->getRHS(),
6227 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6228 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6229 BO->getSourceRange(), BO->getOperatorLoc());
6230 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6231 return setUB(BO->getLHS(),
6232 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6233 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6234 BO->getSourceRange(), BO->getOperatorLoc());
6235 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6236 return setUB(
6237 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6238 /*LessOp=*/llvm::None,
6239 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6240 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6241 if (CE->getNumArgs() == 2) {
6242 auto Op = CE->getOperator();
6243 switch (Op) {
6244 case OO_Greater:
6245 case OO_GreaterEqual:
6246 case OO_Less:
6247 case OO_LessEqual:
6248 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6249 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6250 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6251 CE->getOperatorLoc());
6252 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6253 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6254 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6255 CE->getOperatorLoc());
6256 break;
6257 case OO_ExclaimEqual:
6258 if (IneqCondIsCanonical)
6259 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6260 : CE->getArg(0),
6261 /*LessOp=*/llvm::None,
6262 /*StrictOp=*/true, CE->getSourceRange(),
6263 CE->getOperatorLoc());
6264 break;
6265 default:
6266 break;
6267 }
6268 }
6269 }
6270 if (dependent() || SemaRef.CurContext->isDependentContext())
6271 return false;
6272 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6273 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6274 return true;
6275}
6276
6277bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6278 // RHS of canonical loop form increment can be:
6279 // var + incr
6280 // incr + var
6281 // var - incr
6282 //
6283 RHS = RHS->IgnoreParenImpCasts();
6284 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6285 if (BO->isAdditiveOp()) {
6286 bool IsAdd = BO->getOpcode() == BO_Add;
6287 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6288 return setStep(BO->getRHS(), !IsAdd);
6289 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6290 return setStep(BO->getLHS(), /*Subtract=*/false);
6291 }
6292 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6293 bool IsAdd = CE->getOperator() == OO_Plus;
6294 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6295 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6296 return setStep(CE->getArg(1), !IsAdd);
6297 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6298 return setStep(CE->getArg(0), /*Subtract=*/false);
6299 }
6300 }
6301 if (dependent() || SemaRef.CurContext->isDependentContext())
6302 return false;
6303 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6304 << RHS->getSourceRange() << LCDecl;
6305 return true;
6306}
6307
6308bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6309 // Check incr-expr for canonical loop form and return true if it
6310 // does not conform.
6311 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6312 // ++var
6313 // var++
6314 // --var
6315 // var--
6316 // var += incr
6317 // var -= incr
6318 // var = var + incr
6319 // var = incr + var
6320 // var = var - incr
6321 //
6322 if (!S) {
6323 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6324 return true;
6325 }
6326 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6327 if (!ExprTemp->cleanupsHaveSideEffects())
6328 S = ExprTemp->getSubExpr();
6329
6330 IncrementSrcRange = S->getSourceRange();
6331 S = S->IgnoreParens();
6332 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
6333 if (UO->isIncrementDecrementOp() &&
6334 getInitLCDecl(UO->getSubExpr()) == LCDecl)
6335 return setStep(SemaRef
6336 .ActOnIntegerConstant(UO->getBeginLoc(),
6337 (UO->isDecrementOp() ? -1 : 1))
6338 .get(),
6339 /*Subtract=*/false);
6340 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6341 switch (BO->getOpcode()) {
6342 case BO_AddAssign:
6343 case BO_SubAssign:
6344 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6345 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6346 break;
6347 case BO_Assign:
6348 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6349 return checkAndSetIncRHS(BO->getRHS());
6350 break;
6351 default:
6352 break;
6353 }
6354 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6355 switch (CE->getOperator()) {
6356 case OO_PlusPlus:
6357 case OO_MinusMinus:
6358 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6359 return setStep(SemaRef
6360 .ActOnIntegerConstant(
6361 CE->getBeginLoc(),
6362 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6363 .get(),
6364 /*Subtract=*/false);
6365 break;
6366 case OO_PlusEqual:
6367 case OO_MinusEqual:
6368 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6369 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6370 break;
6371 case OO_Equal:
6372 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6373 return checkAndSetIncRHS(CE->getArg(1));
6374 break;
6375 default:
6376 break;
6377 }
6378 }
6379 if (dependent() || SemaRef.CurContext->isDependentContext())
6380 return false;
6381 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6382 << S->getSourceRange() << LCDecl;
6383 return true;
6384}
6385
6386static ExprResult
6387tryBuildCapture(Sema &SemaRef, Expr *Capture,
6388 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6389 if (SemaRef.CurContext->isDependentContext())
43
Assuming the condition is false
44
Taking false branch
6390 return ExprResult(Capture);
6391 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
45
Called C++ object pointer is null
6392 return SemaRef.PerformImplicitConversion(
6393 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
6394 /*AllowExplicit=*/true);
6395 auto I = Captures.find(Capture);
6396 if (I != Captures.end())
6397 return buildCapture(SemaRef, Capture, I->second);
6398 DeclRefExpr *Ref = nullptr;
6399 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
6400 Captures[Capture] = Ref;
6401 return Res;
6402}
6403
6404/// Build the expression to calculate the number of iterations.
6405Expr *OpenMPIterationSpaceChecker::buildNumIterations(
6406 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6408 ExprResult Diff;
6409 QualType VarType = LCDecl->getType().getNonReferenceType();
6410 if (VarType->isIntegerType() || VarType->isPointerType() ||
6411 SemaRef.getLangOpts().CPlusPlus) {
6412 Expr *LBVal = LB;
6413 Expr *UBVal = UB;
6414 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
6415 // max(LB(MinVal), LB(MaxVal))
6416 if (InitDependOnLC) {
6417 const LoopIterationSpace &IS =
6418 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6419 InitDependOnLC.getValueOr(
6420 CondDependOnLC.getValueOr(0))];
6421 if (!IS.MinValue || !IS.MaxValue)
6422 return nullptr;
6423 // OuterVar = Min
6424 ExprResult MinValue =
6425 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6426 if (!MinValue.isUsable())
6427 return nullptr;
6428
6429 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6430 IS.CounterVar, MinValue.get());
6431 if (!LBMinVal.isUsable())
6432 return nullptr;
6433 // OuterVar = Min, LBVal
6434 LBMinVal =
6435 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
6436 if (!LBMinVal.isUsable())
6437 return nullptr;
6438 // (OuterVar = Min, LBVal)
6439 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
6440 if (!LBMinVal.isUsable())
6441 return nullptr;
6442
6443 // OuterVar = Max
6444 ExprResult MaxValue =
6445 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6446 if (!MaxValue.isUsable())
6447 return nullptr;
6448
6449 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6450 IS.CounterVar, MaxValue.get());
6451 if (!LBMaxVal.isUsable())
6452 return nullptr;
6453 // OuterVar = Max, LBVal
6454 LBMaxVal =
6455 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
6456 if (!LBMaxVal.isUsable())
6457 return nullptr;
6458 // (OuterVar = Max, LBVal)
6459 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
6460 if (!LBMaxVal.isUsable())
6461 return nullptr;
6462
6463 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
6464 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
6465 if (!LBMin || !LBMax)
6466 return nullptr;
6467 // LB(MinVal) < LB(MaxVal)
6468 ExprResult MinLessMaxRes =
6469 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
6470 if (!MinLessMaxRes.isUsable())
6471 return nullptr;
6472 Expr *MinLessMax =
6473 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
6474 if (!MinLessMax)
6475 return nullptr;
6476 if (TestIsLessOp.getValue()) {
6477 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
6478 // LB(MaxVal))
6479 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6480 MinLessMax, LBMin, LBMax);
6481 if (!MinLB.isUsable())
6482 return nullptr;
6483 LBVal = MinLB.get();
6484 } else {
6485 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
6486 // LB(MaxVal))
6487 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6488 MinLessMax, LBMax, LBMin);
6489 if (!MaxLB.isUsable())
6490 return nullptr;
6491 LBVal = MaxLB.get();
6492 }
6493 }
6494 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
6495 // min(UB(MinVal), UB(MaxVal))
6496 if (CondDependOnLC) {
6497 const LoopIterationSpace &IS =
6498 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6499 InitDependOnLC.getValueOr(
6500 CondDependOnLC.getValueOr(0))];
6501 if (!IS.MinValue || !IS.MaxValue)
6502 return nullptr;
6503 // OuterVar = Min
6504 ExprResult MinValue =
6505 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6506 if (!MinValue.isUsable())
6507 return nullptr;
6508
6509 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6510 IS.CounterVar, MinValue.get());
6511 if (!UBMinVal.isUsable())
6512 return nullptr;
6513 // OuterVar = Min, UBVal
6514 UBMinVal =
6515 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
6516 if (!UBMinVal.isUsable())
6517 return nullptr;
6518 // (OuterVar = Min, UBVal)
6519 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
6520 if (!UBMinVal.isUsable())
6521 return nullptr;
6522
6523 // OuterVar = Max
6524 ExprResult MaxValue =
6525 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6526 if (!MaxValue.isUsable())
6527 return nullptr;
6528
6529 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6530 IS.CounterVar, MaxValue.get());
6531 if (!UBMaxVal.isUsable())
6532 return nullptr;
6533 // OuterVar = Max, UBVal
6534 UBMaxVal =
6535 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
6536 if (!UBMaxVal.isUsable())
6537 return nullptr;
6538 // (OuterVar = Max, UBVal)
6539 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
6540 if (!UBMaxVal.isUsable())
6541 return nullptr;
6542
6543 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
6544 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
6545 if (!UBMin || !UBMax)
6546 return nullptr;
6547 // UB(MinVal) > UB(MaxVal)
6548 ExprResult MinGreaterMaxRes =
6549 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
6550 if (!MinGreaterMaxRes.isUsable())
6551 return nullptr;
6552 Expr *MinGreaterMax =
6553 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
6554 if (!MinGreaterMax)
6555 return nullptr;
6556 if (TestIsLessOp.getValue()) {
6557 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
6558 // UB(MaxVal))
6559 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
6560 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
6561 if (!MaxUB.isUsable())
6562 return nullptr;
6563 UBVal = MaxUB.get();
6564 } else {
6565 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
6566 // UB(MaxVal))
6567 ExprResult MinUB = SemaRef.ActOnConditionalOp(
6568 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
6569 if (!MinUB.isUsable())
6570 return nullptr;
6571 UBVal = MinUB.get();
6572 }
6573 }
6574 // Upper - Lower
6575 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
6576 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
6577 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
6578 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
6579 if (!Upper || !Lower)
6580 return nullptr;
6581
6582 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6583
6584 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6585 // BuildBinOp already emitted error, this one is to point user to upper
6586 // and lower bound, and to tell what is passed to 'operator-'.
6587 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6588 << Upper->getSourceRange() << Lower->getSourceRange();
6589 return nullptr;
6590 }
6591 }
6592
6593 if (!Diff.isUsable())
6594 return nullptr;
6595
6596 // Upper - Lower [- 1]
6597 if (TestIsStrictOp)
6598 Diff = SemaRef.BuildBinOp(
6599 S, DefaultLoc, BO_Sub, Diff.get(),
6600 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6601 if (!Diff.isUsable())
6602 return nullptr;
6603
6604 // Upper - Lower [- 1] + Step
6605 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6606 if (!NewStep.isUsable())
6607 return nullptr;
6608 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
6609 if (!Diff.isUsable())
6610 return nullptr;
6611
6612 // Parentheses (for dumping/debugging purposes only).
6613 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6614 if (!Diff.isUsable())
6615 return nullptr;
6616
6617 // (Upper - Lower [- 1] + Step) / Step
6618 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6619 if (!Diff.isUsable())
6620 return nullptr;
6621
6622 // OpenMP runtime requires 32-bit or 64-bit loop variables.
6623 QualType Type = Diff.get()->getType();
6624 ASTContext &C = SemaRef.Context;
6625 bool UseVarType = VarType->hasIntegerRepresentation() &&
6626 C.getTypeSize(Type) > C.getTypeSize(VarType);
6627 if (!Type->isIntegerType() || UseVarType) {
6628 unsigned NewSize =
6629 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
6630 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
6631 : Type->hasSignedIntegerRepresentation();
6632 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
6633 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
6634 Diff = SemaRef.PerformImplicitConversion(
6635 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
6636 if (!Diff.isUsable())
6637 return nullptr;
6638 }
6639 }
6640 if (LimitedType) {
6641 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
6642 if (NewSize != C.getTypeSize(Type)) {
6643 if (NewSize < C.getTypeSize(Type)) {
6644 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6644, __PRETTY_FUNCTION__))
;
6645 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
6646 << InitSrcRange << ConditionSrcRange;
6647 }
6648 QualType NewType = C.getIntTypeForBitwidth(
6649 NewSize, Type->hasSignedIntegerRepresentation() ||
6650 C.getTypeSize(Type) < NewSize);
6651 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
6652 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
6653 Sema::AA_Converting, true);
6654 if (!Diff.isUsable())
6655 return nullptr;
6656 }
6657 }
6658 }
6659
6660 return Diff.get();
6661}
6662
6663std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
6664 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6665 // Do not build for iterators, they cannot be used in non-rectangular loop
6666 // nests.
6667 if (LCDecl->getType()->isRecordType())
6668 return std::make_pair(nullptr, nullptr);
6669 // If we subtract, the min is in the condition, otherwise the min is in the
6670 // init value.
6671 Expr *MinExpr = nullptr;
6672 Expr *MaxExpr = nullptr;
6673 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
6674 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
6675 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
6676 : CondDependOnLC.hasValue();
6677 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
6678 : InitDependOnLC.hasValue();
6679 Expr *Lower =
6680 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
6681 Expr *Upper =
6682 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
6683 if (!Upper || !Lower)
6684 return std::make_pair(nullptr, nullptr);
6685
6686 if (TestIsLessOp.getValue())
6687 MinExpr = Lower;
6688 else
6689 MaxExpr = Upper;
6690
6691 // Build minimum/maximum value based on number of iterations.
6692 ExprResult Diff;
6693 QualType VarType = LCDecl->getType().getNonReferenceType();
6694
6695 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6696 if (!Diff.isUsable())
6697 return std::make_pair(nullptr, nullptr);
6698
6699 // Upper - Lower [- 1]
6700 if (TestIsStrictOp)
6701 Diff = SemaRef.BuildBinOp(
6702 S, DefaultLoc, BO_Sub, Diff.get(),
6703 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6704 if (!Diff.isUsable())
6705 return std::make_pair(nullptr, nullptr);
6706
6707 // Upper - Lower [- 1] + Step
6708 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6709 if (!NewStep.isUsable())
6710 return std::make_pair(nullptr, nullptr);
6711
6712 // Parentheses (for dumping/debugging purposes only).
6713 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6714 if (!Diff.isUsable())
6715 return std::make_pair(nullptr, nullptr);
6716
6717 // (Upper - Lower [- 1]) / Step
6718 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6719 if (!Diff.isUsable())
6720 return std::make_pair(nullptr, nullptr);
6721
6722 // ((Upper - Lower [- 1]) / Step) * Step
6723 // Parentheses (for dumping/debugging purposes only).
6724 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6725 if (!Diff.isUsable())
6726 return std::make_pair(nullptr, nullptr);
6727
6728 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
6729 if (!Diff.isUsable())
6730 return std::make_pair(nullptr, nullptr);
6731
6732 // Convert to the original type or ptrdiff_t, if original type is pointer.
6733 if (!VarType->isAnyPointerType() &&
6734 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) {
6735 Diff = SemaRef.PerformImplicitConversion(
6736 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true);
6737 } else if (VarType->isAnyPointerType() &&
6738 !SemaRef.Context.hasSameType(
6739 Diff.get()->getType(),
6740 SemaRef.Context.getUnsignedPointerDiffType())) {
6741 Diff = SemaRef.PerformImplicitConversion(
6742 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
6743 Sema::AA_Converting, /*AllowExplicit=*/true);
6744 }
6745 if (!Diff.isUsable())
6746 return std::make_pair(nullptr, nullptr);
6747
6748 // Parentheses (for dumping/debugging purposes only).
6749 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6750 if (!Diff.isUsable())
6751 return std::make_pair(nullptr, nullptr);
6752
6753 if (TestIsLessOp.getValue()) {
6754 // MinExpr = Lower;
6755 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
6756 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get());
6757 if (!Diff.isUsable())
6758 return std::make_pair(nullptr, nullptr);
6759 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6760 if (!Diff.isUsable())
6761 return std::make_pair(nullptr, nullptr);
6762 MaxExpr = Diff.get();
6763 } else {
6764 // MaxExpr = Upper;
6765 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
6766 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
6767 if (!Diff.isUsable())
6768 return std::make_pair(nullptr, nullptr);
6769 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6770 if (!Diff.isUsable())
6771 return std::make_pair(nullptr, nullptr);
6772 MinExpr = Diff.get();
6773 }
6774
6775 return std::make_pair(MinExpr, MaxExpr);
6776}
6777
6778Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
6779 if (InitDependOnLC || CondDependOnLC)
6780 return Condition;
6781 return nullptr;
6782}
6783
6784Expr *OpenMPIterationSpaceChecker::buildPreCond(
6785 Scope *S, Expr *Cond,
6786 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6787 // Do not build a precondition when the condition/initialization is dependent
6788 // to prevent pessimistic early loop exit.
6789 // TODO: this can be improved by calculating min/max values but not sure that
6790 // it will be very effective.
6791 if (CondDependOnLC || InitDependOnLC)
22
Calling 'Optional::operator bool'
30
Returning from 'Optional::operator bool'
31
Calling 'Optional::operator bool'
39
Returning from 'Optional::operator bool'
40
Taking false branch
6792 return SemaRef.PerformImplicitConversion(
6793 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
6794 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6795 /*AllowExplicit=*/true).get();
6796
6797 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
6798 Sema::TentativeAnalysisScope Trap(SemaRef);
6799
6800 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
41
Passing null pointer value via 2nd parameter 'Capture'
42
Calling 'tryBuildCapture'
6801 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
6802 if (!NewLB.isUsable() || !NewUB.isUsable())
6803 return nullptr;
6804
6805 ExprResult CondExpr =
6806 SemaRef.BuildBinOp(S, DefaultLoc,
6807 TestIsLessOp.getValue() ?
6808 (TestIsStrictOp ? BO_LT : BO_LE) :
6809 (TestIsStrictOp ? BO_GT : BO_GE),
6810 NewLB.get(), NewUB.get());
6811 if (CondExpr.isUsable()) {
6812 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
6813 SemaRef.Context.BoolTy))
6814 CondExpr = SemaRef.PerformImplicitConversion(
6815 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6816 /*AllowExplicit=*/true);
6817 }
6818
6819 // Otherwise use original loop condition and evaluate it in runtime.
6820 return CondExpr.isUsable() ? CondExpr.get() : Cond;
6821}
6822
6823/// Build reference expression to the counter be used for codegen.
6824DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
6825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6826 DSAStackTy &DSA) const {
6827 auto *VD = dyn_cast<VarDecl>(LCDecl);
6828 if (!VD) {
6829 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
6830 DeclRefExpr *Ref = buildDeclRefExpr(
6831 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
6832 const DSAStackTy::DSAVarData Data =
6833 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
6834 // If the loop control decl is explicitly marked as private, do not mark it
6835 // as captured again.
6836 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
6837 Captures.insert(std::make_pair(LCRef, Ref));
6838 return Ref;
6839 }
6840 return cast<DeclRefExpr>(LCRef);
6841}
6842
6843Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
6844 if (LCDecl && !LCDecl->isInvalidDecl()) {
6845 QualType Type = LCDecl->getType().getNonReferenceType();
6846 VarDecl *PrivateVar = buildVarDecl(
6847 SemaRef, DefaultLoc, Type, LCDecl->getName(),
6848 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
6849 isa<VarDecl>(LCDecl)
6850 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
6851 : nullptr);
6852 if (PrivateVar->isInvalidDecl())
6853 return nullptr;
6854 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
6855 }
6856 return nullptr;
6857}
6858
6859/// Build initialization of the counter to be used for codegen.
6860Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
6861
6862/// Build step of the counter be used for codegen.
6863Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
6864
6865Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
6866 Scope *S, Expr *Counter,
6867 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
6868 Expr *Inc, OverloadedOperatorKind OOK) {
6869 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
6870 if (!Cnt)
6871 return nullptr;
6872 if (Inc) {
6873 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6874, __PRETTY_FUNCTION__))
6874 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6874, __PRETTY_FUNCTION__))
;
6875 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
6876 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
6877 if (!Cnt)
6878 return nullptr;
6879 }
6880 ExprResult Diff;
6881 QualType VarType = LCDecl->getType().getNonReferenceType();
6882 if (VarType->isIntegerType() || VarType->isPointerType() ||
6883 SemaRef.getLangOpts().CPlusPlus) {
6884 // Upper - Lower
6885 Expr *Upper = TestIsLessOp.getValue()
6886 ? Cnt
6887 : tryBuildCapture(SemaRef, UB, Captures).get();
6888 Expr *Lower = TestIsLessOp.getValue()
6889 ? tryBuildCapture(SemaRef, LB, Captures).get()
6890 : Cnt;
6891 if (!Upper || !Lower)
6892 return nullptr;
6893
6894 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6895
6896 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6897 // BuildBinOp already emitted error, this one is to point user to upper
6898 // and lower bound, and to tell what is passed to 'operator-'.
6899 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6900 << Upper->getSourceRange() << Lower->getSourceRange();
6901 return nullptr;
6902 }
6903 }
6904
6905 if (!Diff.isUsable())
6906 return nullptr;
6907
6908 // Parentheses (for dumping/debugging purposes only).
6909 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6910 if (!Diff.isUsable())
6911 return nullptr;
6912
6913 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6914 if (!NewStep.isUsable())
6915 return nullptr;
6916 // (Upper - Lower) / Step
6917 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6918 if (!Diff.isUsable())
6919 return nullptr;
6920
6921 return Diff.get();
6922}
6923} // namespace
6924
6925void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
6926 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6926, __PRETTY_FUNCTION__))
;
6927 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 6927, __PRETTY_FUNCTION__))
;
6928 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
6929 if (AssociatedLoops > 0 &&
6930 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
6931 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->loopStart();
6932 OpenMPIterationSpaceChecker ISC(*this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, ForLoc);
6933 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
6934 if (ValueDecl *D = ISC.getLoopDecl()) {
6935 auto *VD = dyn_cast<VarDecl>(D);
6936 DeclRefExpr *PrivateRef = nullptr;
6937 if (!VD) {
6938 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
6939 VD = Private;
6940 } else {
6941 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
6942 /*WithInit=*/false);
6943 VD = cast<VarDecl>(PrivateRef->getDecl());
6944 }
6945 }
6946 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
6947 const Decl *LD = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getPossiblyLoopCunter();
6948 if (LD != D->getCanonicalDecl()) {
6949 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->resetPossibleLoopCounter();
6950 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
6951 MarkDeclarationsReferencedInExpr(
6952 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
6953 Var->getType().getNonLValueExprType(Context),
6954 ForLoc, /*RefersToCapture=*/true));
6955 }
6956 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
6957 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
6958 // Referenced in a Construct, C/C++]. The loop iteration variable in the
6959 // associated for-loop of a simd construct with just one associated
6960 // for-loop may be listed in a linear clause with a constant-linear-step
6961 // that is the increment of the associated for-loop. The loop iteration
6962 // variable(s) in the associated for-loop(s) of a for or parallel for
6963 // construct may be listed in a private or lastprivate clause.
6964 DSAStackTy::DSAVarData DVar =
6965 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
6966 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
6967 // is declared in the loop and it is predetermined as a private.
6968 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
6969 OpenMPClauseKind PredeterminedCKind =
6970 isOpenMPSimdDirective(DKind)
6971 ? (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
6972 : OMPC_private;
6973 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6974 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
6975 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
6976 DVar.CKind != OMPC_private))) ||
6977 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
6978 DKind == OMPD_master_taskloop ||
6979 DKind == OMPD_parallel_master_taskloop ||
6980 isOpenMPDistributeDirective(DKind)) &&
6981 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6982 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
6983 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
6984 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
6985 << getOpenMPClauseName(DVar.CKind)
6986 << getOpenMPDirectiveName(DKind)
6987 << getOpenMPClauseName(PredeterminedCKind);
6988 if (DVar.RefExpr == nullptr)
6989 DVar.CKind = PredeterminedCKind;
6990 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar,
6991 /*IsLoopIterVar=*/true);
6992 } else if (LoopDeclRefExpr) {
6993 // Make the loop iteration variable private (for worksharing
6994 // constructs), linear (for simd directives with the only one
6995 // associated loop) or lastprivate (for simd directives with several
6996 // collapsed or ordered loops).
6997 if (DVar.CKind == OMPC_unknown)
6998 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
6999 PrivateRef);
7000 }
7001 }
7002 }
7003 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
7004 }
7005}
7006
7007/// Called on a for stmt to check and extract its iteration space
7008/// for further processing (such as collapsing).
7009static bool checkOpenMPIterationSpace(
7010 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7011 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7012 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7013 Expr *OrderedLoopCountExpr,
7014 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7015 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7016 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7017 // OpenMP [2.9.1, Canonical Loop Form]
7018 // for (init-expr; test-expr; incr-expr) structured-block
7019 // for (range-decl: range-expr) structured-block
7020 auto *For = dyn_cast_or_null<ForStmt>(S);
7
Assuming 'S' is a 'ForStmt'
7021 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8
Assuming 'S' is not a 'CXXForRangeStmt'
7022 // Ranged for is supported only in OpenMP 5.0.
7023 if (!For
8.1
'For' is non-null
8.1
'For' is non-null
&& (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7024 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7025 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7026 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7027 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7028 if (TotalNestedLoopCount > 1) {
7029 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7030 SemaRef.Diag(DSA.getConstructLoc(),
7031 diag::note_omp_collapse_ordered_expr)
7032 << 2 << CollapseLoopCountExpr->getSourceRange()
7033 << OrderedLoopCountExpr->getSourceRange();
7034 else if (CollapseLoopCountExpr)
7035 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7036 diag::note_omp_collapse_ordered_expr)
7037 << 0 << CollapseLoopCountExpr->getSourceRange();
7038 else
7039 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7040 diag::note_omp_collapse_ordered_expr)
7041 << 1 << OrderedLoopCountExpr->getSourceRange();
7042 }
7043 return true;
7044 }
7045 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7046, __PRETTY_FUNCTION__))
9
Assuming the condition is true
10
'?' condition is true
7046 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7046, __PRETTY_FUNCTION__))
;
7047
7048 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
12
Calling constructor for 'OpenMPIterationSpaceChecker'
14
Returning from constructor for 'OpenMPIterationSpaceChecker'
7049 For
10.1
'For' is non-null
10.1
'For' is non-null
? For->getForLoc() : CXXFor->getForLoc())
;
11
'?' condition is true
7050
7051 // Check init.
7052 Stmt *Init = For
14.1
'For' is non-null
14.1
'For' is non-null
? For->getInit() : CXXFor->getBeginStmt();
15
'?' condition is true
7053 if (ISC.checkAndSetInit(Init))
16
Taking false branch
7054 return true;
7055
7056 bool HasErrors = false;
7057
7058 // Check loop variable's type.
7059 if (ValueDecl *LCDecl
16.1
'LCDecl' is null
16.1
'LCDecl' is null
= ISC.getLoopDecl()) {
17
Taking false branch
7060 // OpenMP [2.6, Canonical Loop Form]
7061 // Var is one of the following:
7062 // A variable of signed or unsigned integer type.
7063 // For C++, a variable of a random access iterator type.
7064 // For C, a variable of a pointer type.
7065 QualType VarType = LCDecl->getType().getNonReferenceType();
7066 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7067 !VarType->isPointerType() &&
7068 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7069 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7070 << SemaRef.getLangOpts().CPlusPlus;
7071 HasErrors = true;
7072 }
7073
7074 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7075 // a Construct
7076 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7077 // parallel for construct is (are) private.
7078 // The loop iteration variable in the associated for-loop of a simd
7079 // construct with just one associated for-loop is linear with a
7080 // constant-linear-step that is the increment of the associated for-loop.
7081 // Exclude loop var from the list of variables with implicitly defined data
7082 // sharing attributes.
7083 VarsWithImplicitDSA.erase(LCDecl);
7084
7085 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7085, __PRETTY_FUNCTION__))
;
7086
7087 // Check test-expr.
7088 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7089
7090 // Check incr-expr.
7091 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7092 }
7093
7094 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors
18.1
'HasErrors' is false
18.1
'HasErrors' is false
)
18
Assuming the condition is false
19
Taking false branch
7095 return HasErrors;
7096
7097 // Build the loop's iteration space representation.
7098 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
21
Calling 'OpenMPIterationSpaceChecker::buildPreCond'
7099 DSA.getCurScope(), For
19.1
'For' is non-null
19.1
'For' is non-null
? For->getCond() : CXXFor->getCond(), Captures)
;
20
'?' condition is true
7100 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7101 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7102 (isOpenMPWorksharingDirective(DKind) ||
7103 isOpenMPTaskLoopDirective(DKind) ||
7104 isOpenMPDistributeDirective(DKind)),
7105 Captures);
7106 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7107 ISC.buildCounterVar(Captures, DSA);
7108 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7109 ISC.buildPrivateCounterVar();
7110 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7111 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7112 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7113 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7114 ISC.getConditionSrcRange();
7115 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7116 ISC.getIncrementSrcRange();
7117 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7118 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7119 ISC.isStrictTestOp();
7120 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7121 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7122 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7123 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7124 ISC.buildFinalCondition(DSA.getCurScope());
7125 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7126 ISC.doesInitDependOnLC();
7127 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7128 ISC.doesCondDependOnLC();
7129 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7130 ISC.getLoopDependentIdx();
7131
7132 HasErrors |=
7133 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7134 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7135 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7136 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7137 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7138 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7139 if (!HasErrors && DSA.isOrderedRegion()) {
7140 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7141 if (CurrentNestedLoopCount <
7142 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7143 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7144 CurrentNestedLoopCount,
7145 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7146 DSA.getOrderedRegionParam().second->setLoopCounter(
7147 CurrentNestedLoopCount,
7148 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7149 }
7150 }
7151 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7152 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7153 // Erroneous case - clause has some problems.
7154 continue;
7155 }
7156 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7157 Pair.second.size() <= CurrentNestedLoopCount) {
7158 // Erroneous case - clause has some problems.
7159 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7160 continue;
7161 }
7162 Expr *CntValue;
7163 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7164 CntValue = ISC.buildOrderedLoopData(
7165 DSA.getCurScope(),
7166 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7167 Pair.first->getDependencyLoc());
7168 else
7169 CntValue = ISC.buildOrderedLoopData(
7170 DSA.getCurScope(),
7171 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7172 Pair.first->getDependencyLoc(),
7173 Pair.second[CurrentNestedLoopCount].first,
7174 Pair.second[CurrentNestedLoopCount].second);
7175 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7176 }
7177 }
7178
7179 return HasErrors;
7180}
7181
7182/// Build 'VarRef = Start.
7183static ExprResult
7184buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7185 ExprResult Start, bool IsNonRectangularLB,
7186 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7187 // Build 'VarRef = Start.
7188 ExprResult NewStart = IsNonRectangularLB
7189 ? Start.get()
7190 : tryBuildCapture(SemaRef, Start.get(), Captures);
7191 if (!NewStart.isUsable())
7192 return ExprError();
7193 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7194 VarRef.get()->getType())) {
7195 NewStart = SemaRef.PerformImplicitConversion(
7196 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7197 /*AllowExplicit=*/true);
7198 if (!NewStart.isUsable())
7199 return ExprError();
7200 }
7201
7202 ExprResult Init =
7203 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7204 return Init;
7205}
7206
7207/// Build 'VarRef = Start + Iter * Step'.
7208static ExprResult buildCounterUpdate(
7209 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7210 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7211 bool IsNonRectangularLB,
7212 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7213 // Add parentheses (for debugging purposes only).
7214 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7215 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7216 !Step.isUsable())
7217 return ExprError();
7218
7219 ExprResult NewStep = Step;
7220 if (Captures)
7221 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
7222 if (NewStep.isInvalid())
7223 return ExprError();
7224 ExprResult Update =
7225 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
7226 if (!Update.isUsable())
7227 return ExprError();
7228
7229 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
7230 // 'VarRef = Start (+|-) Iter * Step'.
7231 if (!Start.isUsable())
7232 return ExprError();
7233 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
7234 if (!NewStart.isUsable())
7235 return ExprError();
7236 if (Captures && !IsNonRectangularLB)
7237 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
7238 if (NewStart.isInvalid())
7239 return ExprError();
7240
7241 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
7242 ExprResult SavedUpdate = Update;
7243 ExprResult UpdateVal;
7244 if (VarRef.get()->getType()->isOverloadableType() ||
7245 NewStart.get()->getType()->isOverloadableType() ||
7246 Update.get()->getType()->isOverloadableType()) {
7247 Sema::TentativeAnalysisScope Trap(SemaRef);
7248
7249 Update =
7250 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7251 if (Update.isUsable()) {
7252 UpdateVal =
7253 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7254 VarRef.get(), SavedUpdate.get());
7255 if (UpdateVal.isUsable()) {
7256 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
7257 UpdateVal.get());
7258 }
7259 }
7260 }
7261
7262 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
7263 if (!Update.isUsable() || !UpdateVal.isUsable()) {
7264 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7265 NewStart.get(), SavedUpdate.get());
7266 if (!Update.isUsable())
7267 return ExprError();
7268
7269 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
7270 VarRef.get()->getType())) {
7271 Update = SemaRef.PerformImplicitConversion(
7272 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
7273 if (!Update.isUsable())
7274 return ExprError();
7275 }
7276
7277 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
7278 }
7279 return Update;
7280}
7281
7282/// Convert integer expression \a E to make it have at least \a Bits
7283/// bits.
7284static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
7285 if (E == nullptr)
7286 return ExprError();
7287 ASTContext &C = SemaRef.Context;
7288 QualType OldType = E->getType();
7289 unsigned HasBits = C.getTypeSize(OldType);
7290 if (HasBits >= Bits)
7291 return ExprResult(E);
7292 // OK to convert to signed, because new type has more bits than old.
7293 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
7294 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
7295 true);
7296}
7297
7298/// Check if the given expression \a E is a constant integer that fits
7299/// into \a Bits bits.
7300static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
7301 if (E == nullptr)
7302 return false;
7303 llvm::APSInt Result;
7304 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
7305 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
7306 return false;
7307}
7308
7309/// Build preinits statement for the given declarations.
7310static Stmt *buildPreInits(ASTContext &Context,
7311 MutableArrayRef<Decl *> PreInits) {
7312 if (!PreInits.empty()) {
7313 return new (Context) DeclStmt(
7314 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
7315 SourceLocation(), SourceLocation());
7316 }
7317 return nullptr;
7318}
7319
7320/// Build preinits statement for the given declarations.
7321static Stmt *
7322buildPreInits(ASTContext &Context,
7323 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7324 if (!Captures.empty()) {
7325 SmallVector<Decl *, 16> PreInits;
7326 for (const auto &Pair : Captures)
7327 PreInits.push_back(Pair.second->getDecl());
7328 return buildPreInits(Context, PreInits);
7329 }
7330 return nullptr;
7331}
7332
7333/// Build postupdate expression for the given list of postupdates expressions.
7334static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
7335 Expr *PostUpdate = nullptr;
7336 if (!PostUpdates.empty()) {
7337 for (Expr *E : PostUpdates) {
7338 Expr *ConvE = S.BuildCStyleCastExpr(
7339 E->getExprLoc(),
7340 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
7341 E->getExprLoc(), E)
7342 .get();
7343 PostUpdate = PostUpdate
7344 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
7345 PostUpdate, ConvE)
7346 .get()
7347 : ConvE;
7348 }
7349 }
7350 return PostUpdate;
7351}
7352
7353/// Called on a for stmt to check itself and nested loops (if any).
7354/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
7355/// number of collapsed loops otherwise.
7356static unsigned
7357checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
7358 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
7359 DSAStackTy &DSA,
7360 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7361 OMPLoopDirective::HelperExprs &Built) {
7362 unsigned NestedLoopCount = 1;
7363 if (CollapseLoopCountExpr) {
1
Assuming 'CollapseLoopCountExpr' is null
2
Taking false branch
7364 // Found 'collapse' clause - calculate collapse number.
7365 Expr::EvalResult Result;
7366 if (!CollapseLoopCountExpr->isValueDependent() &&
7367 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
7368 NestedLoopCount = Result.Val.getInt().getLimitedValue();
7369 } else {
7370 Built.clear(/*Size=*/1);
7371 return 1;
7372 }
7373 }
7374 unsigned OrderedLoopCount = 1;
7375 if (OrderedLoopCountExpr) {
3
Assuming 'OrderedLoopCountExpr' is null
4
Taking false branch
7376 // Found 'ordered' clause - calculate collapse number.
7377 Expr::EvalResult EVResult;
7378 if (!OrderedLoopCountExpr->isValueDependent() &&
7379 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
7380 SemaRef.getASTContext())) {
7381 llvm::APSInt Result = EVResult.Val.getInt();
7382 if (Result.getLimitedValue() < NestedLoopCount) {
7383 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7384 diag::err_omp_wrong_ordered_loop_count)
7385 << OrderedLoopCountExpr->getSourceRange();
7386 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7387 diag::note_collapse_loop_count)
7388 << CollapseLoopCountExpr->getSourceRange();
7389 }
7390 OrderedLoopCount = Result.getLimitedValue();
7391 } else {
7392 Built.clear(/*Size=*/1);
7393 return 1;
7394 }
7395 }
7396 // This is helper routine for loop directives (e.g., 'for', 'simd',
7397 // 'for simd', etc.).
7398 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
7399 SmallVector<LoopIterationSpace, 4> IterSpaces(
7400 std::max(OrderedLoopCount, NestedLoopCount));
7401 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
7402 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5
Loop condition is true. Entering loop body
7403 if (checkOpenMPIterationSpace(
6
Calling 'checkOpenMPIterationSpace'
7404 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7405 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7406 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7407 return 0;
7408 // Move on to the next nested for loop, or to the loop body.
7409 // OpenMP [2.8.1, simd construct, Restrictions]
7410 // All loops associated with the construct must be perfectly nested; that
7411 // is, there must be no intervening code nor any OpenMP directive between
7412 // any two loops.
7413 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
7414 CurStmt = For->getBody();
7415 } else {
7416 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7417, __PRETTY_FUNCTION__))
7417 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7417, __PRETTY_FUNCTION__))
;
7418 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7419 }
7420 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
7421 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
7422 }
7423 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
7424 if (checkOpenMPIterationSpace(
7425 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7426 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7427 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7428 return 0;
7429 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
7430 // Handle initialization of captured loop iterator variables.
7431 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
7432 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
7433 Captures[DRE] = DRE;
7434 }
7435 }
7436 // Move on to the next nested for loop, or to the loop body.
7437 // OpenMP [2.8.1, simd construct, Restrictions]
7438 // All loops associated with the construct must be perfectly nested; that
7439 // is, there must be no intervening code nor any OpenMP directive between
7440 // any two loops.
7441 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
7442 CurStmt = For->getBody();
7443 } else {
7444 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7445, __PRETTY_FUNCTION__))
7445 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7445, __PRETTY_FUNCTION__))
;
7446 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7447 }
7448 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
7449 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
7450 }
7451
7452 Built.clear(/* size */ NestedLoopCount);
7453
7454 if (SemaRef.CurContext->isDependentContext())
7455 return NestedLoopCount;
7456
7457 // An example of what is generated for the following code:
7458 //
7459 // #pragma omp simd collapse(2) ordered(2)
7460 // for (i = 0; i < NI; ++i)
7461 // for (k = 0; k < NK; ++k)
7462 // for (j = J0; j < NJ; j+=2) {
7463 // <loop body>
7464 // }
7465 //
7466 // We generate the code below.
7467 // Note: the loop body may be outlined in CodeGen.
7468 // Note: some counters may be C++ classes, operator- is used to find number of
7469 // iterations and operator+= to calculate counter value.
7470 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
7471 // or i64 is currently supported).
7472 //
7473 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
7474 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
7475 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
7476 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
7477 // // similar updates for vars in clauses (e.g. 'linear')
7478 // <loop body (using local i and j)>
7479 // }
7480 // i = NI; // assign final values of counters
7481 // j = NJ;
7482 //
7483
7484 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
7485 // the iteration counts of the collapsed for loops.
7486 // Precondition tests if there is at least one iteration (all conditions are
7487 // true).
7488 auto PreCond = ExprResult(IterSpaces[0].PreCond);
7489 Expr *N0 = IterSpaces[0].NumIterations;
7490 ExprResult LastIteration32 =
7491 widenIterationCount(/*Bits=*/32,
7492 SemaRef
7493 .PerformImplicitConversion(
7494 N0->IgnoreImpCasts(), N0->getType(),
7495 Sema::AA_Converting, /*AllowExplicit=*/true)
7496 .get(),
7497 SemaRef);
7498 ExprResult LastIteration64 = widenIterationCount(
7499 /*Bits=*/64,
7500 SemaRef
7501 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
7502 Sema::AA_Converting,
7503 /*AllowExplicit=*/true)
7504 .get(),
7505 SemaRef);
7506
7507 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
7508 return NestedLoopCount;
7509
7510 ASTContext &C = SemaRef.Context;
7511 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
7512
7513 Scope *CurScope = DSA.getCurScope();
7514 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
7515 if (PreCond.isUsable()) {
7516 PreCond =
7517 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
7518 PreCond.get(), IterSpaces[Cnt].PreCond);
7519 }
7520 Expr *N = IterSpaces[Cnt].NumIterations;
7521 SourceLocation Loc = N->getExprLoc();
7522 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
7523 if (LastIteration32.isUsable())
7524 LastIteration32 = SemaRef.BuildBinOp(
7525 CurScope, Loc, BO_Mul, LastIteration32.get(),
7526 SemaRef
7527 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7528 Sema::AA_Converting,
7529 /*AllowExplicit=*/true)
7530 .get());
7531 if (LastIteration64.isUsable())
7532 LastIteration64 = SemaRef.BuildBinOp(
7533 CurScope, Loc, BO_Mul, LastIteration64.get(),
7534 SemaRef
7535 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
7536 Sema::AA_Converting,
7537 /*AllowExplicit=*/true)
7538 .get());
7539 }
7540
7541 // Choose either the 32-bit or 64-bit version.
7542 ExprResult LastIteration = LastIteration64;
7543 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
7544 (LastIteration32.isUsable() &&
7545 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
7546 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
7547 fitsInto(
7548 /*Bits=*/32,
7549 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
7550 LastIteration64.get(), SemaRef))))
7551 LastIteration = LastIteration32;
7552 QualType VType = LastIteration.get()->getType();
7553 QualType RealVType = VType;
7554 QualType StrideVType = VType;
7555 if (isOpenMPTaskLoopDirective(DKind)) {
7556 VType =
7557 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
7558 StrideVType =
7559 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
7560 }
7561
7562 if (!LastIteration.isUsable())
7563 return 0;
7564
7565 // Save the number of iterations.
7566 ExprResult NumIterations = LastIteration;
7567 {
7568 LastIteration = SemaRef.BuildBinOp(
7569 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
7570 LastIteration.get(),
7571 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7572 if (!LastIteration.isUsable())
7573 return 0;
7574 }
7575
7576 // Calculate the last iteration number beforehand instead of doing this on
7577 // each iteration. Do not do this if the number of iterations may be kfold-ed.
7578 llvm::APSInt Result;
7579 bool IsConstant =
7580 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
7581 ExprResult CalcLastIteration;
7582 if (!IsConstant) {
7583 ExprResult SaveRef =
7584 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
7585 LastIteration = SaveRef;
7586
7587 // Prepare SaveRef + 1.
7588 NumIterations = SemaRef.BuildBinOp(
7589 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
7590 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7591 if (!NumIterations.isUsable())
7592 return 0;
7593 }
7594
7595 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
7596
7597 // Build variables passed into runtime, necessary for worksharing directives.
7598 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
7599 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7600 isOpenMPDistributeDirective(DKind)) {
7601 // Lower bound variable, initialized with zero.
7602 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
7603 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
7604 SemaRef.AddInitializerToDecl(LBDecl,
7605 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7606 /*DirectInit*/ false);
7607
7608 // Upper bound variable, initialized with last iteration number.
7609 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
7610 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
7611 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
7612 /*DirectInit*/ false);
7613
7614 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
7615 // This will be used to implement clause 'lastprivate'.
7616 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
7617 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
7618 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
7619 SemaRef.AddInitializerToDecl(ILDecl,
7620 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7621 /*DirectInit*/ false);
7622
7623 // Stride variable returned by runtime (we initialize it to 1 by default).
7624 VarDecl *STDecl =
7625 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
7626 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
7627 SemaRef.AddInitializerToDecl(STDecl,
7628 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
7629 /*DirectInit*/ false);
7630
7631 // Build expression: UB = min(UB, LastIteration)
7632 // It is necessary for CodeGen of directives with static scheduling.
7633 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
7634 UB.get(), LastIteration.get());
7635 ExprResult CondOp = SemaRef.ActOnConditionalOp(
7636 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
7637 LastIteration.get(), UB.get());
7638 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
7639 CondOp.get());
7640 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
7641
7642 // If we have a combined directive that combines 'distribute', 'for' or
7643 // 'simd' we need to be able to access the bounds of the schedule of the
7644 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
7645 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
7646 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7647 // Lower bound variable, initialized with zero.
7648 VarDecl *CombLBDecl =
7649 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
7650 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
7651 SemaRef.AddInitializerToDecl(
7652 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7653 /*DirectInit*/ false);
7654
7655 // Upper bound variable, initialized with last iteration number.
7656 VarDecl *CombUBDecl =
7657 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
7658 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
7659 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
7660 /*DirectInit*/ false);
7661
7662 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
7663 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
7664 ExprResult CombCondOp =
7665 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
7666 LastIteration.get(), CombUB.get());
7667 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
7668 CombCondOp.get());
7669 CombEUB =
7670 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
7671
7672 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
7673 // We expect to have at least 2 more parameters than the 'parallel'
7674 // directive does - the lower and upper bounds of the previous schedule.
7675 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7676, __PRETTY_FUNCTION__))
7676 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7676, __PRETTY_FUNCTION__))
;
7677
7678 // Set the proper type for the bounds given what we learned from the
7679 // enclosed loops.
7680 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
7681 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
7682
7683 // Previous lower and upper bounds are obtained from the region
7684 // parameters.
7685 PrevLB =
7686 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
7687 PrevUB =
7688 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
7689 }
7690 }
7691
7692 // Build the iteration variable and its initialization before loop.
7693 ExprResult IV;
7694 ExprResult Init, CombInit;
7695 {
7696 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
7697 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
7698 Expr *RHS =
7699 (isOpenMPWorksharingDirective(DKind) ||
7700 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
7701 ? LB.get()
7702 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7703 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
7704 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
7705
7706 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7707 Expr *CombRHS =
7708 (isOpenMPWorksharingDirective(DKind) ||
7709 isOpenMPTaskLoopDirective(DKind) ||
7710 isOpenMPDistributeDirective(DKind))
7711 ? CombLB.get()
7712 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7713 CombInit =
7714 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
7715 CombInit =
7716 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
7717 }
7718 }
7719
7720 bool UseStrictCompare =
7721 RealVType->hasUnsignedIntegerRepresentation() &&
7722 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
7723 return LIS.IsStrictCompare;
7724 });
7725 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
7726 // unsigned IV)) for worksharing loops.
7727 SourceLocation CondLoc = AStmt->getBeginLoc();
7728 Expr *BoundUB = UB.get();
7729 if (UseStrictCompare) {
7730 BoundUB =
7731 SemaRef
7732 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
7733 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7734 .get();
7735 BoundUB =
7736 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
7737 }
7738 ExprResult Cond =
7739 (isOpenMPWorksharingDirective(DKind) ||
7740 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
7741 ? SemaRef.BuildBinOp(CurScope, CondLoc,
7742 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
7743 BoundUB)
7744 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7745 NumIterations.get());
7746 ExprResult CombDistCond;
7747 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7748 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7749 NumIterations.get());
7750 }
7751
7752 ExprResult CombCond;
7753 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7754 Expr *BoundCombUB = CombUB.get();
7755 if (UseStrictCompare) {
7756 BoundCombUB =
7757 SemaRef
7758 .BuildBinOp(
7759 CurScope, CondLoc, BO_Add, BoundCombUB,
7760 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7761 .get();
7762 BoundCombUB =
7763 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
7764 .get();
7765 }
7766 CombCond =
7767 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7768 IV.get(), BoundCombUB);
7769 }
7770 // Loop increment (IV = IV + 1)
7771 SourceLocation IncLoc = AStmt->getBeginLoc();
7772 ExprResult Inc =
7773 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
7774 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
7775 if (!Inc.isUsable())
7776 return 0;
7777 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
7778 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
7779 if (!Inc.isUsable())
7780 return 0;
7781
7782 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
7783 // Used for directives with static scheduling.
7784 // In combined construct, add combined version that use CombLB and CombUB
7785 // base variables for the update
7786 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
7787 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
7788 isOpenMPDistributeDirective(DKind)) {
7789 // LB + ST
7790 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
7791 if (!NextLB.isUsable())
7792 return 0;
7793 // LB = LB + ST
7794 NextLB =
7795 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
7796 NextLB =
7797 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
7798 if (!NextLB.isUsable())
7799 return 0;
7800 // UB + ST
7801 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
7802 if (!NextUB.isUsable())
7803 return 0;
7804 // UB = UB + ST
7805 NextUB =
7806 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
7807 NextUB =
7808 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
7809 if (!NextUB.isUsable())
7810 return 0;
7811 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7812 CombNextLB =
7813 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
7814 if (!NextLB.isUsable())
7815 return 0;
7816 // LB = LB + ST
7817 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
7818 CombNextLB.get());
7819 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
7820 /*DiscardedValue*/ false);
7821 if (!CombNextLB.isUsable())
7822 return 0;
7823 // UB + ST
7824 CombNextUB =
7825 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
7826 if (!CombNextUB.isUsable())
7827 return 0;
7828 // UB = UB + ST
7829 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
7830 CombNextUB.get());
7831 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
7832 /*DiscardedValue*/ false);
7833 if (!CombNextUB.isUsable())
7834 return 0;
7835 }
7836 }
7837
7838 // Create increment expression for distribute loop when combined in a same
7839 // directive with for as IV = IV + ST; ensure upper bound expression based
7840 // on PrevUB instead of NumIterations - used to implement 'for' when found
7841 // in combination with 'distribute', like in 'distribute parallel for'
7842 SourceLocation DistIncLoc = AStmt->getBeginLoc();
7843 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
7844 if (isOpenMPLoopBoundSharingDirective(DKind)) {
7845 DistCond = SemaRef.BuildBinOp(
7846 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
7847 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7847, __PRETTY_FUNCTION__))
;
7848
7849 DistInc =
7850 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
7851 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7851, __PRETTY_FUNCTION__))
;
7852 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
7853 DistInc.get());
7854 DistInc =
7855 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
7856 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 7856, __PRETTY_FUNCTION__))
;
7857
7858 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
7859 // construct
7860 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
7861 ExprResult IsUBGreater =
7862 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
7863 ExprResult CondOp = SemaRef.ActOnConditionalOp(
7864 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
7865 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
7866 CondOp.get());
7867 PrevEUB =
7868 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
7869
7870 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
7871 // parallel for is in combination with a distribute directive with
7872 // schedule(static, 1)
7873 Expr *BoundPrevUB = PrevUB.get();
7874 if (UseStrictCompare) {
7875 BoundPrevUB =
7876 SemaRef
7877 .BuildBinOp(
7878 CurScope, CondLoc, BO_Add, BoundPrevUB,
7879 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7880 .get();
7881 BoundPrevUB =
7882 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
7883 .get();
7884 }
7885 ParForInDistCond =
7886 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7887 IV.get(), BoundPrevUB);
7888 }
7889
7890 // Build updates and final values of the loop counters.
7891 bool HasErrors = false;
7892 Built.Counters.resize(NestedLoopCount);
7893 Built.Inits.resize(NestedLoopCount);
7894 Built.Updates.resize(NestedLoopCount);
7895 Built.Finals.resize(NestedLoopCount);
7896 Built.DependentCounters.resize(NestedLoopCount);
7897 Built.DependentInits.resize(NestedLoopCount);
7898 Built.FinalsConditions.resize(NestedLoopCount);
7899 {
7900 // We implement the following algorithm for obtaining the
7901 // original loop iteration variable values based on the
7902 // value of the collapsed loop iteration variable IV.
7903 //
7904 // Let n+1 be the number of collapsed loops in the nest.
7905 // Iteration variables (I0, I1, .... In)
7906 // Iteration counts (N0, N1, ... Nn)
7907 //
7908 // Acc = IV;
7909 //
7910 // To compute Ik for loop k, 0 <= k <= n, generate:
7911 // Prod = N(k+1) * N(k+2) * ... * Nn;
7912 // Ik = Acc / Prod;
7913 // Acc -= Ik * Prod;
7914 //
7915 ExprResult Acc = IV;
7916 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7917 LoopIterationSpace &IS = IterSpaces[Cnt];
7918 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
7919 ExprResult Iter;
7920
7921 // Compute prod
7922 ExprResult Prod =
7923 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7924 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
7925 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
7926 IterSpaces[K].NumIterations);
7927
7928 // Iter = Acc / Prod
7929 // If there is at least one more inner loop to avoid
7930 // multiplication by 1.
7931 if (Cnt + 1 < NestedLoopCount)
7932 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
7933 Acc.get(), Prod.get());
7934 else
7935 Iter = Acc;
7936 if (!Iter.isUsable()) {
7937 HasErrors = true;
7938 break;
7939 }
7940
7941 // Update Acc:
7942 // Acc -= Iter * Prod
7943 // Check if there is at least one more inner loop to avoid
7944 // multiplication by 1.
7945 if (Cnt + 1 < NestedLoopCount)
7946 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
7947 Iter.get(), Prod.get());
7948 else
7949 Prod = Iter;
7950 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
7951 Acc.get(), Prod.get());
7952
7953 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
7954 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
7955 DeclRefExpr *CounterVar = buildDeclRefExpr(
7956 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
7957 /*RefersToCapture=*/true);
7958 ExprResult Init =
7959 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
7960 IS.CounterInit, IS.IsNonRectangularLB, Captures);
7961 if (!Init.isUsable()) {
7962 HasErrors = true;
7963 break;
7964 }
7965 ExprResult Update = buildCounterUpdate(
7966 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
7967 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
7968 if (!Update.isUsable()) {
7969 HasErrors = true;
7970 break;
7971 }
7972
7973 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
7974 ExprResult Final =
7975 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
7976 IS.CounterInit, IS.NumIterations, IS.CounterStep,
7977 IS.Subtract, IS.IsNonRectangularLB, &Captures);
7978 if (!Final.isUsable()) {
7979 HasErrors = true;
7980 break;
7981 }
7982
7983 if (!Update.isUsable() || !Final.isUsable()) {
7984 HasErrors = true;
7985 break;
7986 }
7987 // Save results
7988 Built.Counters[Cnt] = IS.CounterVar;
7989 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
7990 Built.Inits[Cnt] = Init.get();
7991 Built.Updates[Cnt] = Update.get();
7992 Built.Finals[Cnt] = Final.get();
7993 Built.DependentCounters[Cnt] = nullptr;
7994 Built.DependentInits[Cnt] = nullptr;
7995 Built.FinalsConditions[Cnt] = nullptr;
7996 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
7997 Built.DependentCounters[Cnt] =
7998 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
7999 Built.DependentInits[Cnt] =
8000 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8001 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8002 }
8003 }
8004 }
8005
8006 if (HasErrors)
8007 return 0;
8008
8009 // Save results
8010 Built.IterationVarRef = IV.get();
8011 Built.LastIteration = LastIteration.get();
8012 Built.NumIterations = NumIterations.get();
8013 Built.CalcLastIteration = SemaRef
8014 .ActOnFinishFullExpr(CalcLastIteration.get(),
8015 /*DiscardedValue=*/false)
8016 .get();
8017 Built.PreCond = PreCond.get();
8018 Built.PreInits = buildPreInits(C, Captures);
8019 Built.Cond = Cond.get();
8020 Built.Init = Init.get();
8021 Built.Inc = Inc.get();
8022 Built.LB = LB.get();
8023 Built.UB = UB.get();
8024 Built.IL = IL.get();
8025 Built.ST = ST.get();
8026 Built.EUB = EUB.get();
8027 Built.NLB = NextLB.get();
8028 Built.NUB = NextUB.get();
8029 Built.PrevLB = PrevLB.get();
8030 Built.PrevUB = PrevUB.get();
8031 Built.DistInc = DistInc.get();
8032 Built.PrevEUB = PrevEUB.get();
8033 Built.DistCombinedFields.LB = CombLB.get();
8034 Built.DistCombinedFields.UB = CombUB.get();
8035 Built.DistCombinedFields.EUB = CombEUB.get();
8036 Built.DistCombinedFields.Init = CombInit.get();
8037 Built.DistCombinedFields.Cond = CombCond.get();
8038 Built.DistCombinedFields.NLB = CombNextLB.get();
8039 Built.DistCombinedFields.NUB = CombNextUB.get();
8040 Built.DistCombinedFields.DistCond = CombDistCond.get();
8041 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8042
8043 return NestedLoopCount;
8044}
8045
8046static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8047 auto CollapseClauses =
8048 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8049 if (CollapseClauses.begin() != CollapseClauses.end())
8050 return (*CollapseClauses.begin())->getNumForLoops();
8051 return nullptr;
8052}
8053
8054static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8055 auto OrderedClauses =
8056 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8057 if (OrderedClauses.begin() != OrderedClauses.end())
8058 return (*OrderedClauses.begin())->getNumForLoops();
8059 return nullptr;
8060}
8061
8062static bool checkSimdlenSafelenSpecified(Sema &S,
8063 const ArrayRef<OMPClause *> Clauses) {
8064 const OMPSafelenClause *Safelen = nullptr;
8065 const OMPSimdlenClause *Simdlen = nullptr;
8066
8067 for (const OMPClause *Clause : Clauses) {
8068 if (Clause->getClauseKind() == OMPC_safelen)
8069 Safelen = cast<OMPSafelenClause>(Clause);
8070 else if (Clause->getClauseKind() == OMPC_simdlen)
8071 Simdlen = cast<OMPSimdlenClause>(Clause);
8072 if (Safelen && Simdlen)
8073 break;
8074 }
8075
8076 if (Simdlen && Safelen) {
8077 const Expr *SimdlenLength = Simdlen->getSimdlen();
8078 const Expr *SafelenLength = Safelen->getSafelen();
8079 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8080 SimdlenLength->isInstantiationDependent() ||
8081 SimdlenLength->containsUnexpandedParameterPack())
8082 return false;
8083 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8084 SafelenLength->isInstantiationDependent() ||
8085 SafelenLength->containsUnexpandedParameterPack())
8086 return false;
8087 Expr::EvalResult SimdlenResult, SafelenResult;
8088 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8089 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8090 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8091 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8092 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8093 // If both simdlen and safelen clauses are specified, the value of the
8094 // simdlen parameter must be less than or equal to the value of the safelen
8095 // parameter.
8096 if (SimdlenRes > SafelenRes) {
8097 S.Diag(SimdlenLength->getExprLoc(),
8098 diag::err_omp_wrong_simdlen_safelen_values)
8099 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8100 return true;
8101 }
8102 }
8103 return false;
8104}
8105
8106StmtResult
8107Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8108 SourceLocation StartLoc, SourceLocation EndLoc,
8109 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8110 if (!AStmt)
8111 return StmtError();
8112
8113 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8113, __PRETTY_FUNCTION__))
;
8114 OMPLoopDirective::HelperExprs B;
8115 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8116 // define the nested loops number.
8117 unsigned NestedLoopCount = checkOpenMPLoop(
8118 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8119 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8120 if (NestedLoopCount == 0)
8121 return StmtError();
8122
8123 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8124, __PRETTY_FUNCTION__))
8124 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8124, __PRETTY_FUNCTION__))
;
8125
8126 if (!CurContext->isDependentContext()) {
8127 // Finalize the clauses that need pre-built expressions for CodeGen.
8128 for (OMPClause *C : Clauses) {
8129 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8130 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8131 B.NumIterations, *this, CurScope,
8132 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8133 return StmtError();
8134 }
8135 }
8136
8137 if (checkSimdlenSafelenSpecified(*this, Clauses))
8138 return StmtError();
8139
8140 setFunctionHasBranchProtectedScope();
8141 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8142 Clauses, AStmt, B);
8143}
8144
8145StmtResult
8146Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8147 SourceLocation StartLoc, SourceLocation EndLoc,
8148 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8149 if (!AStmt)
8150 return StmtError();
8151
8152 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8152, __PRETTY_FUNCTION__))
;
8153 OMPLoopDirective::HelperExprs B;
8154 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8155 // define the nested loops number.
8156 unsigned NestedLoopCount = checkOpenMPLoop(
8157 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8158 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
8159 if (NestedLoopCount == 0)
8160 return StmtError();
8161
8162 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8163, __PRETTY_FUNCTION__))
8163 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8163, __PRETTY_FUNCTION__))
;
8164
8165 if (!CurContext->isDependentContext()) {
8166 // Finalize the clauses that need pre-built expressions for CodeGen.
8167 for (OMPClause *C : Clauses) {
8168 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8169 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8170 B.NumIterations, *this, CurScope,
8171 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8172 return StmtError();
8173 }
8174 }
8175
8176 setFunctionHasBranchProtectedScope();
8177 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8178 Clauses, AStmt, B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8179}
8180
8181StmtResult Sema::ActOnOpenMPForSimdDirective(
8182 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8183 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8184 if (!AStmt)
8185 return StmtError();
8186
8187 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8187, __PRETTY_FUNCTION__))
;
8188 OMPLoopDirective::HelperExprs B;
8189 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8190 // define the nested loops number.
8191 unsigned NestedLoopCount =
8192 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8193 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
8194 VarsWithImplicitDSA, B);
8195 if (NestedLoopCount == 0)
8196 return StmtError();
8197
8198 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8199, __PRETTY_FUNCTION__))
8199 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8199, __PRETTY_FUNCTION__))
;
8200
8201 if (!CurContext->isDependentContext()) {
8202 // Finalize the clauses that need pre-built expressions for CodeGen.
8203 for (OMPClause *C : Clauses) {
8204 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8205 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8206 B.NumIterations, *this, CurScope,
8207 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8208 return StmtError();
8209 }
8210 }
8211
8212 if (checkSimdlenSafelenSpecified(*this, Clauses))
8213 return StmtError();
8214
8215 setFunctionHasBranchProtectedScope();
8216 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8217 Clauses, AStmt, B);
8218}
8219
8220StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
8221 Stmt *AStmt,
8222 SourceLocation StartLoc,
8223 SourceLocation EndLoc) {
8224 if (!AStmt)
8225 return StmtError();
8226
8227 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8227, __PRETTY_FUNCTION__))
;
8228 auto BaseStmt = AStmt;
8229 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8230 BaseStmt = CS->getCapturedStmt();
8231 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8232 auto S = C->children();
8233 if (S.begin() == S.end())
8234 return StmtError();
8235 // All associated statements must be '#pragma omp section' except for
8236 // the first one.
8237 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8238 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8239 if (SectionStmt)
8240 Diag(SectionStmt->getBeginLoc(),
8241 diag::err_omp_sections_substmt_not_section);
8242 return StmtError();
8243 }
8244 cast<OMPSectionDirective>(SectionStmt)
8245 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8246 }
8247 } else {
8248 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
8249 return StmtError();
8250 }
8251
8252 setFunctionHasBranchProtectedScope();
8253
8254 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8255 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8256}
8257
8258StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
8259 SourceLocation StartLoc,
8260 SourceLocation EndLoc) {
8261 if (!AStmt)
8262 return StmtError();
8263
8264 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8264, __PRETTY_FUNCTION__))
;
8265
8266 setFunctionHasBranchProtectedScope();
8267 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8268
8269 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
8270 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8271}
8272
8273StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
8274 Stmt *AStmt,
8275 SourceLocation StartLoc,
8276 SourceLocation EndLoc) {
8277 if (!AStmt)
8278 return StmtError();
8279
8280 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8280, __PRETTY_FUNCTION__))
;
8281
8282 setFunctionHasBranchProtectedScope();
8283
8284 // OpenMP [2.7.3, single Construct, Restrictions]
8285 // The copyprivate clause must not be used with the nowait clause.
8286 const OMPClause *Nowait = nullptr;
8287 const OMPClause *Copyprivate = nullptr;
8288 for (const OMPClause *Clause : Clauses) {
8289 if (Clause->getClauseKind() == OMPC_nowait)
8290 Nowait = Clause;
8291 else if (Clause->getClauseKind() == OMPC_copyprivate)
8292 Copyprivate = Clause;
8293 if (Copyprivate && Nowait) {
8294 Diag(Copyprivate->getBeginLoc(),
8295 diag::err_omp_single_copyprivate_with_nowait);
8296 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
8297 return StmtError();
8298 }
8299 }
8300
8301 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8302}
8303
8304StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
8305 SourceLocation StartLoc,
8306 SourceLocation EndLoc) {
8307 if (!AStmt)
8308 return StmtError();
8309
8310 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8310, __PRETTY_FUNCTION__))
;
8311
8312 setFunctionHasBranchProtectedScope();
8313
8314 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
8315}
8316
8317StmtResult Sema::ActOnOpenMPCriticalDirective(
8318 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
8319 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
8320 if (!AStmt)
8321 return StmtError();
8322
8323 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8323, __PRETTY_FUNCTION__))
;
8324
8325 bool ErrorFound = false;
8326 llvm::APSInt Hint;
8327 SourceLocation HintLoc;
8328 bool DependentHint = false;
8329 for (const OMPClause *C : Clauses) {
8330 if (C->getClauseKind() == OMPC_hint) {
8331 if (!DirName.getName()) {
8332 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
8333 ErrorFound = true;
8334 }
8335 Expr *E = cast<OMPHintClause>(C)->getHint();
8336 if (E->isTypeDependent() || E->isValueDependent() ||
8337 E->isInstantiationDependent()) {
8338 DependentHint = true;
8339 } else {
8340 Hint = E->EvaluateKnownConstInt(Context);
8341 HintLoc = C->getBeginLoc();
8342 }
8343 }
8344 }
8345 if (ErrorFound)
8346 return StmtError();
8347 const auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
8348 if (Pair.first && DirName.getName() && !DependentHint) {
8349 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
8350 Diag(StartLoc, diag::err_omp_critical_with_hint);
8351 if (HintLoc.isValid())
8352 Diag(HintLoc, diag::note_omp_critical_hint_here)
8353 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
8354 else
8355 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
8356 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
8357 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
8358 << 1
8359 << C->getHint()->EvaluateKnownConstInt(Context).toString(
8360 /*Radix=*/10, /*Signed=*/false);
8361 } else {
8362 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
8363 }
8364 }
8365 }
8366
8367 setFunctionHasBranchProtectedScope();
8368
8369 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
8370 Clauses, AStmt);
8371 if (!Pair.first && DirName.getName() && !DependentHint)
8372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
8373 return Dir;
8374}
8375
8376StmtResult Sema::ActOnOpenMPParallelForDirective(
8377 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8378 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8379 if (!AStmt)
8380 return StmtError();
8381
8382 auto *CS = cast<CapturedStmt>(AStmt);
8383 // 1.2.2 OpenMP Language Terminology
8384 // Structured block - An executable statement with a single entry at the
8385 // top and a single exit at the bottom.
8386 // The point of exit cannot be a branch out of the structured block.
8387 // longjmp() and throw() must not violate the entry/exit criteria.
8388 CS->getCapturedDecl()->setNothrow();
8389
8390 OMPLoopDirective::HelperExprs B;
8391 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8392 // define the nested loops number.
8393 unsigned NestedLoopCount =
8394 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
8395 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
8396 VarsWithImplicitDSA, B);
8397 if (NestedLoopCount == 0)
8398 return StmtError();
8399
8400 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8401, __PRETTY_FUNCTION__))
8401 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8401, __PRETTY_FUNCTION__))
;
8402
8403 if (!CurContext->isDependentContext()) {
8404 // Finalize the clauses that need pre-built expressions for CodeGen.
8405 for (OMPClause *C : Clauses) {
8406 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8407 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8408 B.NumIterations, *this, CurScope,
8409 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8410 return StmtError();
8411 }
8412 }
8413
8414 setFunctionHasBranchProtectedScope();
8415 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
8416 NestedLoopCount, Clauses, AStmt, B,
8417 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8418}
8419
8420StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
8421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8422 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8423 if (!AStmt)
8424 return StmtError();
8425
8426 auto *CS = cast<CapturedStmt>(AStmt);
8427 // 1.2.2 OpenMP Language Terminology
8428 // Structured block - An executable statement with a single entry at the
8429 // top and a single exit at the bottom.
8430 // The point of exit cannot be a branch out of the structured block.
8431 // longjmp() and throw() must not violate the entry/exit criteria.
8432 CS->getCapturedDecl()->setNothrow();
8433
8434 OMPLoopDirective::HelperExprs B;
8435 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8436 // define the nested loops number.
8437 unsigned NestedLoopCount =
8438 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
8439 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
8440 VarsWithImplicitDSA, B);
8441 if (NestedLoopCount == 0)
8442 return StmtError();
8443
8444 if (!CurContext->isDependentContext()) {
8445 // Finalize the clauses that need pre-built expressions for CodeGen.
8446 for (OMPClause *C : Clauses) {
8447 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8448 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8449 B.NumIterations, *this, CurScope,
8450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
8451 return StmtError();
8452 }
8453 }
8454
8455 if (checkSimdlenSafelenSpecified(*this, Clauses))
8456 return StmtError();
8457
8458 setFunctionHasBranchProtectedScope();
8459 return OMPParallelForSimdDirective::Create(
8460 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8461}
8462
8463StmtResult
8464Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
8465 Stmt *AStmt, SourceLocation StartLoc,
8466 SourceLocation EndLoc) {
8467 if (!AStmt)
8468 return StmtError();
8469
8470 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8470, __PRETTY_FUNCTION__))
;
8471 auto *CS = cast<CapturedStmt>(AStmt);
8472 // 1.2.2 OpenMP Language Terminology
8473 // Structured block - An executable statement with a single entry at the
8474 // top and a single exit at the bottom.
8475 // The point of exit cannot be a branch out of the structured block.
8476 // longjmp() and throw() must not violate the entry/exit criteria.
8477 CS->getCapturedDecl()->setNothrow();
8478
8479 setFunctionHasBranchProtectedScope();
8480
8481 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses,
8482 AStmt);
8483}
8484
8485StmtResult
8486Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
8487 Stmt *AStmt, SourceLocation StartLoc,
8488 SourceLocation EndLoc) {
8489 if (!AStmt)
8490 return StmtError();
8491
8492 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8492, __PRETTY_FUNCTION__))
;
8493 auto BaseStmt = AStmt;
8494 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8495 BaseStmt = CS->getCapturedStmt();
8496 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8497 auto S = C->children();
8498 if (S.begin() == S.end())
8499 return StmtError();
8500 // All associated statements must be '#pragma omp section' except for
8501 // the first one.
8502 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8503 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8504 if (SectionStmt)
8505 Diag(SectionStmt->getBeginLoc(),
8506 diag::err_omp_parallel_sections_substmt_not_section);
8507 return StmtError();
8508 }
8509 cast<OMPSectionDirective>(SectionStmt)
8510 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8511 }
8512 } else {
8513 Diag(AStmt->getBeginLoc(),
8514 diag::err_omp_parallel_sections_not_compound_stmt);
8515 return StmtError();
8516 }
8517
8518 setFunctionHasBranchProtectedScope();
8519
8520 return OMPParallelSectionsDirective::Create(
8521 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8522}
8523
8524StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
8525 Stmt *AStmt, SourceLocation StartLoc,
8526 SourceLocation EndLoc) {
8527 if (!AStmt)
8528 return StmtError();
8529
8530 auto *CS = cast<CapturedStmt>(AStmt);
8531 // 1.2.2 OpenMP Language Terminology
8532 // Structured block - An executable statement with a single entry at the
8533 // top and a single exit at the bottom.
8534 // The point of exit cannot be a branch out of the structured block.
8535 // longjmp() and throw() must not violate the entry/exit criteria.
8536 CS->getCapturedDecl()->setNothrow();
8537
8538 setFunctionHasBranchProtectedScope();
8539
8540 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8541 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
8542}
8543
8544StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
8545 SourceLocation EndLoc) {
8546 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
8547}
8548
8549StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
8550 SourceLocation EndLoc) {
8551 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
8552}
8553
8554StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
8555 SourceLocation EndLoc) {
8556 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
8557}
8558
8559StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
8560 Stmt *AStmt,
8561 SourceLocation StartLoc,
8562 SourceLocation EndLoc) {
8563 if (!AStmt)
8564 return StmtError();
8565
8566 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8566, __PRETTY_FUNCTION__))
;
8567
8568 setFunctionHasBranchProtectedScope();
8569
8570 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
8571 AStmt,
8572 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
8573}
8574
8575StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
8576 SourceLocation StartLoc,
8577 SourceLocation EndLoc) {
8578 OMPFlushClause *FC = nullptr;
8579 OMPClause *OrderClause = nullptr;
8580 for (OMPClause *C : Clauses) {
8581 if (C->getClauseKind() == OMPC_flush)
8582 FC = cast<OMPFlushClause>(C);
8583 else
8584 OrderClause = C;
8585 }
8586 OpenMPClauseKind MemOrderKind = OMPC_unknown;
8587 SourceLocation MemOrderLoc;
8588 for (const OMPClause *C : Clauses) {
8589 if (C->getClauseKind() == OMPC_acq_rel ||
8590 C->getClauseKind() == OMPC_acquire ||
8591 C->getClauseKind() == OMPC_release) {
8592 if (MemOrderKind != OMPC_unknown) {
8593 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
8594 << getOpenMPDirectiveName(OMPD_flush) << 1
8595 << SourceRange(C->getBeginLoc(), C->getEndLoc());
8596 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
8597 << getOpenMPClauseName(MemOrderKind);
8598 } else {
8599 MemOrderKind = C->getClauseKind();
8600 MemOrderLoc = C->getBeginLoc();
8601 }
8602 }
8603 }
8604 if (FC && OrderClause) {
8605 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
8606 << getOpenMPClauseName(OrderClause->getClauseKind());
8607 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
8608 << getOpenMPClauseName(OrderClause->getClauseKind());
8609 return StmtError();
8610 }
8611 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
8612}
8613
8614StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
8615 SourceLocation StartLoc,
8616 SourceLocation EndLoc) {
8617 if (Clauses.empty()) {
8618 Diag(StartLoc, diag::err_omp_depobj_expected);
8619 return StmtError();
8620 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
8621 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
8622 return StmtError();
8623 }
8624 // Only depobj expression and another single clause is allowed.
8625 if (Clauses.size() > 2) {
8626 Diag(Clauses[2]->getBeginLoc(),
8627 diag::err_omp_depobj_single_clause_expected);
8628 return StmtError();
8629 } else if (Clauses.size() < 1) {
8630 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
8631 return StmtError();
8632 }
8633 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
8634}
8635
8636StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
8637 Stmt *AStmt,
8638 SourceLocation StartLoc,
8639 SourceLocation EndLoc) {
8640 const OMPClause *DependFound = nullptr;
8641 const OMPClause *DependSourceClause = nullptr;
8642 const OMPClause *DependSinkClause = nullptr;
8643 bool ErrorFound = false;
8644 const OMPThreadsClause *TC = nullptr;
8645 const OMPSIMDClause *SC = nullptr;
8646 for (const OMPClause *C : Clauses) {
8647 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
8648 DependFound = C;
8649 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
8650 if (DependSourceClause) {
8651 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
8652 << getOpenMPDirectiveName(OMPD_ordered)
8653 << getOpenMPClauseName(OMPC_depend) << 2;
8654 ErrorFound = true;
8655 } else {
8656 DependSourceClause = C;
8657 }
8658 if (DependSinkClause) {
8659 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8660 << 0;
8661 ErrorFound = true;
8662 }
8663 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
8664 if (DependSourceClause) {
8665 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8666 << 1;
8667 ErrorFound = true;
8668 }
8669 DependSinkClause = C;
8670 }
8671 } else if (C->getClauseKind() == OMPC_threads) {
8672 TC = cast<OMPThreadsClause>(C);
8673 } else if (C->getClauseKind() == OMPC_simd) {
8674 SC = cast<OMPSIMDClause>(C);
8675 }
8676 }
8677 if (!ErrorFound && !SC &&
8678 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
8679 // OpenMP [2.8.1,simd Construct, Restrictions]
8680 // An ordered construct with the simd clause is the only OpenMP construct
8681 // that can appear in the simd region.
8682 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
8683 << (LangOpts.OpenMP >= 50 ? 1 : 0);
8684 ErrorFound = true;
8685 } else if (DependFound && (TC || SC)) {
8686 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
8687 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
8688 ErrorFound = true;
8689 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
8690 Diag(DependFound->getBeginLoc(),
8691 diag::err_omp_ordered_directive_without_param);
8692 ErrorFound = true;
8693 } else if (TC || Clauses.empty()) {
8694 if (const Expr *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
8695 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
8696 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
8697 << (TC != nullptr);
8698 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
8699 ErrorFound = true;
8700 }
8701 }
8702 if ((!AStmt && !DependFound) || ErrorFound)
8703 return StmtError();
8704
8705 if (AStmt) {
8706 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 8706, __PRETTY_FUNCTION__))
;
8707
8708 setFunctionHasBranchProtectedScope();
8709 }
8710
8711 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8712}
8713
8714namespace {
8715/// Helper class for checking expression in 'omp atomic [update]'
8716/// construct.
8717class OpenMPAtomicUpdateChecker {
8718 /// Error results for atomic update expressions.
8719 enum ExprAnalysisErrorCode {
8720 /// A statement is not an expression statement.
8721 NotAnExpression,
8722 /// Expression is not builtin binary or unary operation.
8723 NotABinaryOrUnaryExpression,
8724 /// Unary operation is not post-/pre- increment/decrement operation.
8725 NotAnUnaryIncDecExpression,
8726 /// An expression is not of scalar type.
8727 NotAScalarType,
8728 /// A binary operation is not an assignment operation.
8729 NotAnAssignmentOp,
8730 /// RHS part of the binary operation is not a binary expression.
8731 NotABinaryExpression,
8732 /// RHS part is not additive/multiplicative/shift/biwise binary
8733 /// expression.
8734 NotABinaryOperator,
8735 /// RHS binary operation does not have reference to the updated LHS
8736 /// part.
8737 NotAnUpdateExpression,
8738 /// No errors is found.
8739 NoError
8740 };
8741 /// Reference to Sema.
8742 Sema &SemaRef;
8743 /// A location for note diagnostics (when error is found).
8744 SourceLocation NoteLoc;
8745 /// 'x' lvalue part of the source atomic expression.
8746 Expr *X;
8747 /// 'expr' rvalue part of the source atomic expression.
8748 Expr *E;
8749 /// Helper expression of the form
8750 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8751 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8752 Expr *UpdateExpr;
8753 /// Is 'x' a LHS in a RHS part of full update expression. It is
8754 /// important for non-associative operations.
8755 bool IsXLHSInRHSPart;
8756 BinaryOperatorKind Op;
8757 SourceLocation OpLoc;
8758 /// true if the source expression is a postfix unary operation, false
8759 /// if it is a prefix unary operation.
8760 bool IsPostfixUpdate;
8761
8762public:
8763 OpenMPAtomicUpdateChecker(Sema &SemaRef)
8764 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
8765 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
8766 /// Check specified statement that it is suitable for 'atomic update'
8767 /// constructs and extract 'x', 'expr' and Operation from the original
8768 /// expression. If DiagId and NoteId == 0, then only check is performed
8769 /// without error notification.
8770 /// \param DiagId Diagnostic which should be emitted if error is found.
8771 /// \param NoteId Diagnostic note for the main error message.
8772 /// \return true if statement is not an update expression, false otherwise.
8773 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
8774 /// Return the 'x' lvalue part of the source atomic expression.
8775 Expr *getX() const { return X; }
8776 /// Return the 'expr' rvalue part of the source atomic expression.
8777 Expr *getExpr() const { return E; }
8778 /// Return the update expression used in calculation of the updated
8779 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8780 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8781 Expr *getUpdateExpr() const { return UpdateExpr; }
8782 /// Return true if 'x' is LHS in RHS part of full update expression,
8783 /// false otherwise.
8784 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
8785
8786 /// true if the source expression is a postfix unary operation, false
8787 /// if it is a prefix unary operation.
8788 bool isPostfixUpdate() const { return IsPostfixUpdate; }
8789
8790private:
8791 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
8792 unsigned NoteId = 0);
8793};
8794} // namespace
8795
8796bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
8797 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
8798 ExprAnalysisErrorCode ErrorFound = NoError;
8799 SourceLocation ErrorLoc, NoteLoc;
8800 SourceRange ErrorRange, NoteRange;
8801 // Allowed constructs are:
8802 // x = x binop expr;
8803 // x = expr binop x;
8804 if (AtomicBinOp->getOpcode() == BO_Assign) {
8805 X = AtomicBinOp->getLHS();
8806 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
8807 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
8808 if (AtomicInnerBinOp->isMultiplicativeOp() ||
8809 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
8810 AtomicInnerBinOp->isBitwiseOp()) {
8811 Op = AtomicInnerBinOp->getOpcode();
8812 OpLoc = AtomicInnerBinOp->getOperatorLoc();
8813 Expr *LHS = AtomicInnerBinOp->getLHS();
8814 Expr *RHS = AtomicInnerBinOp->getRHS();
8815 llvm::FoldingSetNodeID XId, LHSId, RHSId;
8816 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
8817 /*Canonical=*/true);
8818 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
8819 /*Canonical=*/true);
8820 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
8821 /*Canonical=*/true);
8822 if (XId == LHSId) {
8823 E = RHS;
8824 IsXLHSInRHSPart = true;
8825 } else if (XId == RHSId) {
8826 E = LHS;
8827 IsXLHSInRHSPart = false;
8828 } else {
8829 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8830 ErrorRange = AtomicInnerBinOp->getSourceRange();
8831 NoteLoc = X->getExprLoc();
8832 NoteRange = X->getSourceRange();
8833 ErrorFound = NotAnUpdateExpression;
8834 }
8835 } else {
8836 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8837 ErrorRange = AtomicInnerBinOp->getSourceRange();
8838 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
8839 NoteRange = SourceRange(NoteLoc, NoteLoc);
8840 ErrorFound = NotABinaryOperator;
8841 }
8842 } else {
8843 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
8844 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
8845 ErrorFound = NotABinaryExpression;
8846 }
8847 } else {
8848 ErrorLoc = AtomicBinOp->getExprLoc();
8849 ErrorRange = AtomicBinOp->getSourceRange();
8850 NoteLoc = AtomicBinOp->getOperatorLoc();
8851 NoteRange = SourceRange(NoteLoc, NoteLoc);
8852 ErrorFound = NotAnAssignmentOp;
8853 }
8854 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8855 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8856 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8857 return true;
8858 }
8859 if (SemaRef.CurContext->isDependentContext())
8860 E = X = UpdateExpr = nullptr;
8861 return ErrorFound != NoError;
8862}
8863
8864bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
8865 unsigned NoteId) {
8866 ExprAnalysisErrorCode ErrorFound = NoError;
8867 SourceLocation ErrorLoc, NoteLoc;
8868 SourceRange ErrorRange, NoteRange;
8869 // Allowed constructs are:
8870 // x++;
8871 // x--;
8872 // ++x;
8873 // --x;
8874 // x binop= expr;
8875 // x = x binop expr;
8876 // x = expr binop x;
8877 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
8878 AtomicBody = AtomicBody->IgnoreParenImpCasts();
8879 if (AtomicBody->getType()->isScalarType() ||
8880 AtomicBody->isInstantiationDependent()) {
8881 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
8882 AtomicBody->IgnoreParenImpCasts())) {
8883 // Check for Compound Assignment Operation
8884 Op = BinaryOperator::getOpForCompoundAssignment(
8885 AtomicCompAssignOp->getOpcode());
8886 OpLoc = AtomicCompAssignOp->getOperatorLoc();
8887 E = AtomicCompAssignOp->getRHS();
8888 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
8889 IsXLHSInRHSPart = true;
8890 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
8891 AtomicBody->IgnoreParenImpCasts())) {
8892 // Check for Binary Operation
8893 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
8894 return true;
8895 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
8896 AtomicBody->IgnoreParenImpCasts())) {
8897 // Check for Unary Operation
8898 if (AtomicUnaryOp->isIncrementDecrementOp()) {
8899 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
8900 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
8901 OpLoc = AtomicUnaryOp->getOperatorLoc();
8902 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
8903 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
8904 IsXLHSInRHSPart = true;
8905 } else {
8906 ErrorFound = NotAnUnaryIncDecExpression;
8907 ErrorLoc = AtomicUnaryOp->getExprLoc();
8908 ErrorRange = AtomicUnaryOp->getSourceRange();
8909 NoteLoc = AtomicUnaryOp->getOperatorLoc();
8910 NoteRange = SourceRange(NoteLoc, NoteLoc);
8911 }
8912 } else if (!AtomicBody->isInstantiationDependent()) {
8913 ErrorFound = NotABinaryOrUnaryExpression;
8914 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
8915 NoteRange = ErrorRange = AtomicBody->getSourceRange();
8916 }
8917 } else {
8918 ErrorFound = NotAScalarType;
8919 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
8920 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8921 }
8922 } else {
8923 ErrorFound = NotAnExpression;
8924 NoteLoc = ErrorLoc = S->getBeginLoc();
8925 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8926 }
8927 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8928 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8929 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8930 return true;
8931 }
8932 if (SemaRef.CurContext->isDependentContext())
8933 E = X = UpdateExpr = nullptr;
8934 if (ErrorFound == NoError && E && X) {
8935 // Build an update expression of form 'OpaqueValueExpr(x) binop
8936 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
8937 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
8938 auto *OVEX = new (SemaRef.getASTContext())
8939 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
8940 auto *OVEExpr = new (SemaRef.getASTContext())
8941 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
8942 ExprResult Update =
8943 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
8944 IsXLHSInRHSPart ? OVEExpr : OVEX);
8945 if (Update.isInvalid())
8946 return true;
8947 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
8948 Sema::AA_Casting);
8949 if (Update.isInvalid())
8950 return true;
8951 UpdateExpr = Update.get();
8952 }
8953 return ErrorFound != NoError;
8954}
8955
8956StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
8957 Stmt *AStmt,
8958 SourceLocation StartLoc,
8959 SourceLocation EndLoc) {
8960 // Register location of the first atomic directive.
8961 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addAtomicDirectiveLoc(StartLoc);
8962 if (!AStmt)
8963 return StmtError();
8964
8965 auto *CS = cast<CapturedStmt>(AStmt);
8966 // 1.2.2 OpenMP Language Terminology
8967 // Structured block - An executable statement with a single entry at the
8968 // top and a single exit at the bottom.
8969 // The point of exit cannot be a branch out of the structured block.
8970 // longjmp() and throw() must not violate the entry/exit criteria.
8971 OpenMPClauseKind AtomicKind = OMPC_unknown;
8972 SourceLocation AtomicKindLoc;
8973 OpenMPClauseKind MemOrderKind = OMPC_unknown;
8974 SourceLocation MemOrderLoc;
8975 for (const OMPClause *C : Clauses) {
8976 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
8977 C->getClauseKind() == OMPC_update ||
8978 C->getClauseKind() == OMPC_capture) {
8979 if (AtomicKind != OMPC_unknown) {
8980 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
8981 << SourceRange(C->getBeginLoc(), C->getEndLoc());
8982 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
8983 << getOpenMPClauseName(AtomicKind);
8984 } else {
8985 AtomicKind = C->getClauseKind();
8986 AtomicKindLoc = C->getBeginLoc();
8987 }
8988 }
8989 if (C->getClauseKind() == OMPC_seq_cst ||
8990 C->getClauseKind() == OMPC_acq_rel ||
8991 C->getClauseKind() == OMPC_acquire ||
8992 C->getClauseKind() == OMPC_release ||
8993 C->getClauseKind() == OMPC_relaxed) {
8994 if (MemOrderKind != OMPC_unknown) {
8995 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
8996 << getOpenMPDirectiveName(OMPD_atomic) << 0
8997 << SourceRange(C->getBeginLoc(), C->getEndLoc());
8998 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
8999 << getOpenMPClauseName(MemOrderKind);
9000 } else {
9001 MemOrderKind = C->getClauseKind();
9002 MemOrderLoc = C->getBeginLoc();
9003 }
9004 }
9005 }
9006 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9007 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9008 // release.
9009 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9010 // acquire.
9011 // If atomic-clause is update or not present then memory-order-clause must not
9012 // be acq_rel or acquire.
9013 if ((AtomicKind == OMPC_read &&
9014 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9015 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9016 AtomicKind == OMPC_unknown) &&
9017 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9018 SourceLocation Loc = AtomicKindLoc;
9019 if (AtomicKind == OMPC_unknown)
9020 Loc = StartLoc;
9021 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9022 << getOpenMPClauseName(AtomicKind)
9023 << (AtomicKind == OMPC_unknown ? 1 : 0)
9024 << getOpenMPClauseName(MemOrderKind);
9025 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9026 << getOpenMPClauseName(MemOrderKind);
9027 }
9028
9029 Stmt *Body = CS->getCapturedStmt();
9030 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9031 Body = EWC->getSubExpr();
9032
9033 Expr *X = nullptr;
9034 Expr *V = nullptr;
9035 Expr *E = nullptr;
9036 Expr *UE = nullptr;
9037 bool IsXLHSInRHSPart = false;
9038 bool IsPostfixUpdate = false;
9039 // OpenMP [2.12.6, atomic Construct]
9040 // In the next expressions:
9041 // * x and v (as applicable) are both l-value expressions with scalar type.
9042 // * During the execution of an atomic region, multiple syntactic
9043 // occurrences of x must designate the same storage location.
9044 // * Neither of v and expr (as applicable) may access the storage location
9045 // designated by x.
9046 // * Neither of x and expr (as applicable) may access the storage location
9047 // designated by v.
9048 // * expr is an expression with scalar type.
9049 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9050 // * binop, binop=, ++, and -- are not overloaded operators.
9051 // * The expression x binop expr must be numerically equivalent to x binop
9052 // (expr). This requirement is satisfied if the operators in expr have
9053 // precedence greater than binop, or by using parentheses around expr or
9054 // subexpressions of expr.
9055 // * The expression expr binop x must be numerically equivalent to (expr)
9056 // binop x. This requirement is satisfied if the operators in expr have
9057 // precedence equal to or greater than binop, or by using parentheses around
9058 // expr or subexpressions of expr.
9059 // * For forms that allow multiple occurrences of x, the number of times
9060 // that x is evaluated is unspecified.
9061 if (AtomicKind == OMPC_read) {
9062 enum {
9063 NotAnExpression,
9064 NotAnAssignmentOp,
9065 NotAScalarType,
9066 NotAnLValue,
9067 NoError
9068 } ErrorFound = NoError;
9069 SourceLocation ErrorLoc, NoteLoc;
9070 SourceRange ErrorRange, NoteRange;
9071 // If clause is read:
9072 // v = x;
9073 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9074 const auto *AtomicBinOp =
9075 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9076 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9077 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9078 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9079 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9080 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9081 if (!X->isLValue() || !V->isLValue()) {
9082 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9083 ErrorFound = NotAnLValue;
9084 ErrorLoc = AtomicBinOp->getExprLoc();
9085 ErrorRange = AtomicBinOp->getSourceRange();
9086 NoteLoc = NotLValueExpr->getExprLoc();
9087 NoteRange = NotLValueExpr->getSourceRange();
9088 }
9089 } else if (!X->isInstantiationDependent() ||
9090 !V->isInstantiationDependent()) {
9091 const Expr *NotScalarExpr =
9092 (X->isInstantiationDependent() || X->getType()->isScalarType())
9093 ? V
9094 : X;
9095 ErrorFound = NotAScalarType;
9096 ErrorLoc = AtomicBinOp->getExprLoc();
9097 ErrorRange = AtomicBinOp->getSourceRange();
9098 NoteLoc = NotScalarExpr->getExprLoc();
9099 NoteRange = NotScalarExpr->getSourceRange();
9100 }
9101 } else if (!AtomicBody->isInstantiationDependent()) {
9102 ErrorFound = NotAnAssignmentOp;
9103 ErrorLoc = AtomicBody->getExprLoc();
9104 ErrorRange = AtomicBody->getSourceRange();
9105 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9106 : AtomicBody->getExprLoc();
9107 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9108 : AtomicBody->getSourceRange();
9109 }
9110 } else {
9111 ErrorFound = NotAnExpression;
9112 NoteLoc = ErrorLoc = Body->getBeginLoc();
9113 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9114 }
9115 if (ErrorFound != NoError) {
9116 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9117 << ErrorRange;
9118 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9119 << NoteRange;
9120 return StmtError();
9121 }
9122 if (CurContext->isDependentContext())
9123 V = X = nullptr;
9124 } else if (AtomicKind == OMPC_write) {
9125 enum {
9126 NotAnExpression,
9127 NotAnAssignmentOp,
9128 NotAScalarType,
9129 NotAnLValue,
9130 NoError
9131 } ErrorFound = NoError;
9132 SourceLocation ErrorLoc, NoteLoc;
9133 SourceRange ErrorRange, NoteRange;
9134 // If clause is write:
9135 // x = expr;
9136 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9137 const auto *AtomicBinOp =
9138 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9139 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9140 X = AtomicBinOp->getLHS();
9141 E = AtomicBinOp->getRHS();
9142 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9143 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
9144 if (!X->isLValue()) {
9145 ErrorFound = NotAnLValue;
9146 ErrorLoc = AtomicBinOp->getExprLoc();
9147 ErrorRange = AtomicBinOp->getSourceRange();
9148 NoteLoc = X->getExprLoc();
9149 NoteRange = X->getSourceRange();
9150 }
9151 } else if (!X->isInstantiationDependent() ||
9152 !E->isInstantiationDependent()) {
9153 const Expr *NotScalarExpr =
9154 (X->isInstantiationDependent() || X->getType()->isScalarType())
9155 ? E
9156 : X;
9157 ErrorFound = NotAScalarType;
9158 ErrorLoc = AtomicBinOp->getExprLoc();
9159 ErrorRange = AtomicBinOp->getSourceRange();
9160 NoteLoc = NotScalarExpr->getExprLoc();
9161 NoteRange = NotScalarExpr->getSourceRange();
9162 }
9163 } else if (!AtomicBody->isInstantiationDependent()) {
9164 ErrorFound = NotAnAssignmentOp;
9165 ErrorLoc = AtomicBody->getExprLoc();
9166 ErrorRange = AtomicBody->getSourceRange();
9167 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9168 : AtomicBody->getExprLoc();
9169 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9170 : AtomicBody->getSourceRange();
9171 }
9172 } else {
9173 ErrorFound = NotAnExpression;
9174 NoteLoc = ErrorLoc = Body->getBeginLoc();
9175 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9176 }
9177 if (ErrorFound != NoError) {
9178 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
9179 << ErrorRange;
9180 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9181 << NoteRange;
9182 return StmtError();
9183 }
9184 if (CurContext->isDependentContext())
9185 E = X = nullptr;
9186 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
9187 // If clause is update:
9188 // x++;
9189 // x--;
9190 // ++x;
9191 // --x;
9192 // x binop= expr;
9193 // x = x binop expr;
9194 // x = expr binop x;
9195 OpenMPAtomicUpdateChecker Checker(*this);
9196 if (Checker.checkStatement(
9197 Body, (AtomicKind == OMPC_update)
9198 ? diag::err_omp_atomic_update_not_expression_statement
9199 : diag::err_omp_atomic_not_expression_statement,
9200 diag::note_omp_atomic_update))
9201 return StmtError();
9202 if (!CurContext->isDependentContext()) {
9203 E = Checker.getExpr();
9204 X = Checker.getX();
9205 UE = Checker.getUpdateExpr();
9206 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9207 }
9208 } else if (AtomicKind == OMPC_capture) {
9209 enum {
9210 NotAnAssignmentOp,
9211 NotACompoundStatement,
9212 NotTwoSubstatements,
9213 NotASpecificExpression,
9214 NoError
9215 } ErrorFound = NoError;
9216 SourceLocation ErrorLoc, NoteLoc;
9217 SourceRange ErrorRange, NoteRange;
9218 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9219 // If clause is a capture:
9220 // v = x++;
9221 // v = x--;
9222 // v = ++x;
9223 // v = --x;
9224 // v = x binop= expr;
9225 // v = x = x binop expr;
9226 // v = x = expr binop x;
9227 const auto *AtomicBinOp =
9228 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9229 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9230 V = AtomicBinOp->getLHS();
9231 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9232 OpenMPAtomicUpdateChecker Checker(*this);
9233 if (Checker.checkStatement(
9234 Body, diag::err_omp_atomic_capture_not_expression_statement,
9235 diag::note_omp_atomic_update))
9236 return StmtError();
9237 E = Checker.getExpr();
9238 X = Checker.getX();
9239 UE = Checker.getUpdateExpr();
9240 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9241 IsPostfixUpdate = Checker.isPostfixUpdate();
9242 } else if (!AtomicBody->isInstantiationDependent()) {
9243 ErrorLoc = AtomicBody->getExprLoc();
9244 ErrorRange = AtomicBody->getSourceRange();
9245 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9246 : AtomicBody->getExprLoc();
9247 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9248 : AtomicBody->getSourceRange();
9249 ErrorFound = NotAnAssignmentOp;
9250 }
9251 if (ErrorFound != NoError) {
9252 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
9253 << ErrorRange;
9254 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9255 return StmtError();
9256 }
9257 if (CurContext->isDependentContext())
9258 UE = V = E = X = nullptr;
9259 } else {
9260 // If clause is a capture:
9261 // { v = x; x = expr; }
9262 // { v = x; x++; }
9263 // { v = x; x--; }
9264 // { v = x; ++x; }
9265 // { v = x; --x; }
9266 // { v = x; x binop= expr; }
9267 // { v = x; x = x binop expr; }
9268 // { v = x; x = expr binop x; }
9269 // { x++; v = x; }
9270 // { x--; v = x; }
9271 // { ++x; v = x; }
9272 // { --x; v = x; }
9273 // { x binop= expr; v = x; }
9274 // { x = x binop expr; v = x; }
9275 // { x = expr binop x; v = x; }
9276 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
9277 // Check that this is { expr1; expr2; }
9278 if (CS->size() == 2) {
9279 Stmt *First = CS->body_front();
9280 Stmt *Second = CS->body_back();
9281 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
9282 First = EWC->getSubExpr()->IgnoreParenImpCasts();
9283 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
9284 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
9285 // Need to find what subexpression is 'v' and what is 'x'.
9286 OpenMPAtomicUpdateChecker Checker(*this);
9287 bool IsUpdateExprFound = !Checker.checkStatement(Second);
9288 BinaryOperator *BinOp = nullptr;
9289 if (IsUpdateExprFound) {
9290 BinOp = dyn_cast<BinaryOperator>(First);
9291 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
9292 }
9293 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9294 // { v = x; x++; }
9295 // { v = x; x--; }
9296 // { v = x; ++x; }
9297 // { v = x; --x; }
9298 // { v = x; x binop= expr; }
9299 // { v = x; x = x binop expr; }
9300 // { v = x; x = expr binop x; }
9301 // Check that the first expression has form v = x.
9302 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
9303 llvm::FoldingSetNodeID XId, PossibleXId;
9304 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
9305 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
9306 IsUpdateExprFound = XId == PossibleXId;
9307 if (IsUpdateExprFound) {
9308 V = BinOp->getLHS();
9309 X = Checker.getX();
9310 E = Checker.getExpr();
9311 UE = Checker.getUpdateExpr();
9312 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9313 IsPostfixUpdate = true;
9314 }
9315 }
9316 if (!IsUpdateExprFound) {
9317 IsUpdateExprFound = !Checker.checkStatement(First);
9318 BinOp = nullptr;
9319 if (IsUpdateExprFound) {
9320 BinOp = dyn_cast<BinaryOperator>(Second);
9321 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
9322 }
9323 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9324 // { x++; v = x; }
9325 // { x--; v = x; }
9326 // { ++x; v = x; }
9327 // { --x; v = x; }
9328 // { x binop= expr; v = x; }
9329 // { x = x binop expr; v = x; }
9330 // { x = expr binop x; v = x; }
9331 // Check that the second expression has form v = x.
9332 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
9333 llvm::FoldingSetNodeID XId, PossibleXId;
9334 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
9335 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
9336 IsUpdateExprFound = XId == PossibleXId;
9337 if (IsUpdateExprFound) {
9338 V = BinOp->getLHS();
9339 X = Checker.getX();
9340 E = Checker.getExpr();
9341 UE = Checker.getUpdateExpr();
9342 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9343 IsPostfixUpdate = false;
9344 }
9345 }
9346 }
9347 if (!IsUpdateExprFound) {
9348 // { v = x; x = expr; }
9349 auto *FirstExpr = dyn_cast<Expr>(First);
9350 auto *SecondExpr = dyn_cast<Expr>(Second);
9351 if (!FirstExpr || !SecondExpr ||
9352 !(FirstExpr->isInstantiationDependent() ||
9353 SecondExpr->isInstantiationDependent())) {
9354 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
9355 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
9356 ErrorFound = NotAnAssignmentOp;
9357 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
9358 : First->getBeginLoc();
9359 NoteRange = ErrorRange = FirstBinOp
9360 ? FirstBinOp->getSourceRange()
9361 : SourceRange(ErrorLoc, ErrorLoc);
9362 } else {
9363 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
9364 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
9365 ErrorFound = NotAnAssignmentOp;
9366 NoteLoc = ErrorLoc = SecondBinOp
9367 ? SecondBinOp->getOperatorLoc()
9368 : Second->getBeginLoc();
9369 NoteRange = ErrorRange =
9370 SecondBinOp ? SecondBinOp->getSourceRange()
9371 : SourceRange(ErrorLoc, ErrorLoc);
9372 } else {
9373 Expr *PossibleXRHSInFirst =
9374 FirstBinOp->getRHS()->IgnoreParenImpCasts();
9375 Expr *PossibleXLHSInSecond =
9376 SecondBinOp->getLHS()->IgnoreParenImpCasts();
9377 llvm::FoldingSetNodeID X1Id, X2Id;
9378 PossibleXRHSInFirst->Profile(X1Id, Context,
9379 /*Canonical=*/true);
9380 PossibleXLHSInSecond->Profile(X2Id, Context,
9381 /*Canonical=*/true);
9382 IsUpdateExprFound = X1Id == X2Id;
9383 if (IsUpdateExprFound) {
9384 V = FirstBinOp->getLHS();
9385 X = SecondBinOp->getLHS();
9386 E = SecondBinOp->getRHS();
9387 UE = nullptr;
9388 IsXLHSInRHSPart = false;
9389 IsPostfixUpdate = true;
9390 } else {
9391 ErrorFound = NotASpecificExpression;
9392 ErrorLoc = FirstBinOp->getExprLoc();
9393 ErrorRange = FirstBinOp->getSourceRange();
9394 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
9395 NoteRange = SecondBinOp->getRHS()->getSourceRange();
9396 }
9397 }
9398 }
9399 }
9400 }
9401 } else {
9402 NoteLoc = ErrorLoc = Body->getBeginLoc();
9403 NoteRange = ErrorRange =
9404 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
9405 ErrorFound = NotTwoSubstatements;
9406 }
9407 } else {
9408 NoteLoc = ErrorLoc = Body->getBeginLoc();
9409 NoteRange = ErrorRange =
9410 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
9411 ErrorFound = NotACompoundStatement;
9412 }
9413 if (ErrorFound != NoError) {
9414 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
9415 << ErrorRange;
9416 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9417 return StmtError();
9418 }
9419 if (CurContext->isDependentContext())
9420 UE = V = E = X = nullptr;
9421 }
9422 }
9423
9424 setFunctionHasBranchProtectedScope();
9425
9426 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9427 X, V, E, UE, IsXLHSInRHSPart,
9428 IsPostfixUpdate);
9429}
9430
9431StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
9432 Stmt *AStmt,
9433 SourceLocation StartLoc,
9434 SourceLocation EndLoc) {
9435 if (!AStmt)
9436 return StmtError();
9437
9438 auto *CS = cast<CapturedStmt>(AStmt);
9439 // 1.2.2 OpenMP Language Terminology
9440 // Structured block - An executable statement with a single entry at the
9441 // top and a single exit at the bottom.
9442 // The point of exit cannot be a branch out of the structured block.
9443 // longjmp() and throw() must not violate the entry/exit criteria.
9444 CS->getCapturedDecl()->setNothrow();
9445 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
9446 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9447 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9448 // 1.2.2 OpenMP Language Terminology
9449 // Structured block - An executable statement with a single entry at the
9450 // top and a single exit at the bottom.
9451 // The point of exit cannot be a branch out of the structured block.
9452 // longjmp() and throw() must not violate the entry/exit criteria.
9453 CS->getCapturedDecl()->setNothrow();
9454 }
9455
9456 // OpenMP [2.16, Nesting of Regions]
9457 // If specified, a teams construct must be contained within a target
9458 // construct. That target construct must contain no statements or directives
9459 // outside of the teams construct.
9460 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
9461 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
9462 bool OMPTeamsFound = true;
9463 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
9464 auto I = CS->body_begin();
9465 while (I != CS->body_end()) {
9466 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
9467 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
9468 OMPTeamsFound) {
9469
9470 OMPTeamsFound = false;
9471 break;
9472 }
9473 ++I;
9474 }
9475 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9475, __PRETTY_FUNCTION__))
;
9476 S = *I;
9477 } else {
9478 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
9479 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
9480 }
9481 if (!OMPTeamsFound) {
9482 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
9483 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
9484 diag::note_omp_nested_teams_construct_here);
9485 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
9486 << isa<OMPExecutableDirective>(S);
9487 return StmtError();
9488 }
9489 }
9490
9491 setFunctionHasBranchProtectedScope();
9492
9493 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9494}
9495
9496StmtResult
9497Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
9498 Stmt *AStmt, SourceLocation StartLoc,
9499 SourceLocation EndLoc) {
9500 if (!AStmt)
9501 return StmtError();
9502
9503 auto *CS = cast<CapturedStmt>(AStmt);
9504 // 1.2.2 OpenMP Language Terminology
9505 // Structured block - An executable statement with a single entry at the
9506 // top and a single exit at the bottom.
9507 // The point of exit cannot be a branch out of the structured block.
9508 // longjmp() and throw() must not violate the entry/exit criteria.
9509 CS->getCapturedDecl()->setNothrow();
9510 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
9511 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9512 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9513 // 1.2.2 OpenMP Language Terminology
9514 // Structured block - An executable statement with a single entry at the
9515 // top and a single exit at the bottom.
9516 // The point of exit cannot be a branch out of the structured block.
9517 // longjmp() and throw() must not violate the entry/exit criteria.
9518 CS->getCapturedDecl()->setNothrow();
9519 }
9520
9521 setFunctionHasBranchProtectedScope();
9522
9523 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9524 AStmt);
9525}
9526
9527StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
9528 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9529 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9530 if (!AStmt)
9531 return StmtError();
9532
9533 auto *CS = cast<CapturedStmt>(AStmt);
9534 // 1.2.2 OpenMP Language Terminology
9535 // Structured block - An executable statement with a single entry at the
9536 // top and a single exit at the bottom.
9537 // The point of exit cannot be a branch out of the structured block.
9538 // longjmp() and throw() must not violate the entry/exit criteria.
9539 CS->getCapturedDecl()->setNothrow();
9540 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
9541 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9542 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9543 // 1.2.2 OpenMP Language Terminology
9544 // Structured block - An executable statement with a single entry at the
9545 // top and a single exit at the bottom.
9546 // The point of exit cannot be a branch out of the structured block.
9547 // longjmp() and throw() must not violate the entry/exit criteria.
9548 CS->getCapturedDecl()->setNothrow();
9549 }
9550
9551 OMPLoopDirective::HelperExprs B;
9552 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9553 // define the nested loops number.
9554 unsigned NestedLoopCount =
9555 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
9556 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9557 VarsWithImplicitDSA, B);
9558 if (NestedLoopCount == 0)
9559 return StmtError();
9560
9561 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9562, __PRETTY_FUNCTION__))
9562 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9562, __PRETTY_FUNCTION__))
;
9563
9564 if (!CurContext->isDependentContext()) {
9565 // Finalize the clauses that need pre-built expressions for CodeGen.
9566 for (OMPClause *C : Clauses) {
9567 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9568 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9569 B.NumIterations, *this, CurScope,
9570 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9571 return StmtError();
9572 }
9573 }
9574
9575 setFunctionHasBranchProtectedScope();
9576 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
9577 NestedLoopCount, Clauses, AStmt,
9578 B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9579}
9580
9581/// Check for existence of a map clause in the list of clauses.
9582static bool hasClauses(ArrayRef<OMPClause *> Clauses,
9583 const OpenMPClauseKind K) {
9584 return llvm::any_of(
9585 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
9586}
9587
9588template <typename... Params>
9589static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
9590 const Params... ClauseTypes) {
9591 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
9592}
9593
9594StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
9595 Stmt *AStmt,
9596 SourceLocation StartLoc,
9597 SourceLocation EndLoc) {
9598 if (!AStmt)
9599 return StmtError();
9600
9601 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9601, __PRETTY_FUNCTION__))
;
9602
9603 // OpenMP [2.10.1, Restrictions, p. 97]
9604 // At least one map clause must appear on the directive.
9605 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
9606 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9607 << "'map' or 'use_device_ptr'"
9608 << getOpenMPDirectiveName(OMPD_target_data);
9609 return StmtError();
9610 }
9611
9612 setFunctionHasBranchProtectedScope();
9613
9614 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9615 AStmt);
9616}
9617
9618StmtResult
9619Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
9620 SourceLocation StartLoc,
9621 SourceLocation EndLoc, Stmt *AStmt) {
9622 if (!AStmt)
9623 return StmtError();
9624
9625 auto *CS = cast<CapturedStmt>(AStmt);
9626 // 1.2.2 OpenMP Language Terminology
9627 // Structured block - An executable statement with a single entry at the
9628 // top and a single exit at the bottom.
9629 // The point of exit cannot be a branch out of the structured block.
9630 // longjmp() and throw() must not violate the entry/exit criteria.
9631 CS->getCapturedDecl()->setNothrow();
9632 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
9633 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9634 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9635 // 1.2.2 OpenMP Language Terminology
9636 // Structured block - An executable statement with a single entry at the
9637 // top and a single exit at the bottom.
9638 // The point of exit cannot be a branch out of the structured block.
9639 // longjmp() and throw() must not violate the entry/exit criteria.
9640 CS->getCapturedDecl()->setNothrow();
9641 }
9642
9643 // OpenMP [2.10.2, Restrictions, p. 99]
9644 // At least one map clause must appear on the directive.
9645 if (!hasClauses(Clauses, OMPC_map)) {
9646 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9647 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
9648 return StmtError();
9649 }
9650
9651 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9652 AStmt);
9653}
9654
9655StmtResult
9656Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
9657 SourceLocation StartLoc,
9658 SourceLocation EndLoc, Stmt *AStmt) {
9659 if (!AStmt)
9660 return StmtError();
9661
9662 auto *CS = cast<CapturedStmt>(AStmt);
9663 // 1.2.2 OpenMP Language Terminology
9664 // Structured block - An executable statement with a single entry at the
9665 // top and a single exit at the bottom.
9666 // The point of exit cannot be a branch out of the structured block.
9667 // longjmp() and throw() must not violate the entry/exit criteria.
9668 CS->getCapturedDecl()->setNothrow();
9669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
9670 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9671 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9672 // 1.2.2 OpenMP Language Terminology
9673 // Structured block - An executable statement with a single entry at the
9674 // top and a single exit at the bottom.
9675 // The point of exit cannot be a branch out of the structured block.
9676 // longjmp() and throw() must not violate the entry/exit criteria.
9677 CS->getCapturedDecl()->setNothrow();
9678 }
9679
9680 // OpenMP [2.10.3, Restrictions, p. 102]
9681 // At least one map clause must appear on the directive.
9682 if (!hasClauses(Clauses, OMPC_map)) {
9683 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9684 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
9685 return StmtError();
9686 }
9687
9688 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9689 AStmt);
9690}
9691
9692StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
9693 SourceLocation StartLoc,
9694 SourceLocation EndLoc,
9695 Stmt *AStmt) {
9696 if (!AStmt)
9697 return StmtError();
9698
9699 auto *CS = cast<CapturedStmt>(AStmt);
9700 // 1.2.2 OpenMP Language Terminology
9701 // Structured block - An executable statement with a single entry at the
9702 // top and a single exit at the bottom.
9703 // The point of exit cannot be a branch out of the structured block.
9704 // longjmp() and throw() must not violate the entry/exit criteria.
9705 CS->getCapturedDecl()->setNothrow();
9706 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
9707 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9708 CS = cast<CapturedStmt>(CS->getCapturedStmt());
9709 // 1.2.2 OpenMP Language Terminology
9710 // Structured block - An executable statement with a single entry at the
9711 // top and a single exit at the bottom.
9712 // The point of exit cannot be a branch out of the structured block.
9713 // longjmp() and throw() must not violate the entry/exit criteria.
9714 CS->getCapturedDecl()->setNothrow();
9715 }
9716
9717 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
9718 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
9719 return StmtError();
9720 }
9721 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
9722 AStmt);
9723}
9724
9725StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
9726 Stmt *AStmt, SourceLocation StartLoc,
9727 SourceLocation EndLoc) {
9728 if (!AStmt)
9729 return StmtError();
9730
9731 auto *CS = cast<CapturedStmt>(AStmt);
9732 // 1.2.2 OpenMP Language Terminology
9733 // Structured block - An executable statement with a single entry at the
9734 // top and a single exit at the bottom.
9735 // The point of exit cannot be a branch out of the structured block.
9736 // longjmp() and throw() must not violate the entry/exit criteria.
9737 CS->getCapturedDecl()->setNothrow();
9738
9739 setFunctionHasBranchProtectedScope();
9740
9741 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
9742
9743 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9744}
9745
9746StmtResult
9747Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
9748 SourceLocation EndLoc,
9749 OpenMPDirectiveKind CancelRegion) {
9750 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
9751 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
9752 return StmtError();
9753 }
9754 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
9755 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
9756 return StmtError();
9757 }
9758 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
9759 CancelRegion);
9760}
9761
9762StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
9763 SourceLocation StartLoc,
9764 SourceLocation EndLoc,
9765 OpenMPDirectiveKind CancelRegion) {
9766 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
9767 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
9768 return StmtError();
9769 }
9770 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
9771 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
9772 return StmtError();
9773 }
9774 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
9775 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9776 CancelRegion);
9777}
9778
9779static bool checkGrainsizeNumTasksClauses(Sema &S,
9780 ArrayRef<OMPClause *> Clauses) {
9781 const OMPClause *PrevClause = nullptr;
9782 bool ErrorFound = false;
9783 for (const OMPClause *C : Clauses) {
9784 if (C->getClauseKind() == OMPC_grainsize ||
9785 C->getClauseKind() == OMPC_num_tasks) {
9786 if (!PrevClause)
9787 PrevClause = C;
9788 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9789 S.Diag(C->getBeginLoc(),
9790 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
9791 << getOpenMPClauseName(C->getClauseKind())
9792 << getOpenMPClauseName(PrevClause->getClauseKind());
9793 S.Diag(PrevClause->getBeginLoc(),
9794 diag::note_omp_previous_grainsize_num_tasks)
9795 << getOpenMPClauseName(PrevClause->getClauseKind());
9796 ErrorFound = true;
9797 }
9798 }
9799 }
9800 return ErrorFound;
9801}
9802
9803static bool checkReductionClauseWithNogroup(Sema &S,
9804 ArrayRef<OMPClause *> Clauses) {
9805 const OMPClause *ReductionClause = nullptr;
9806 const OMPClause *NogroupClause = nullptr;
9807 for (const OMPClause *C : Clauses) {
9808 if (C->getClauseKind() == OMPC_reduction) {
9809 ReductionClause = C;
9810 if (NogroupClause)
9811 break;
9812 continue;
9813 }
9814 if (C->getClauseKind() == OMPC_nogroup) {
9815 NogroupClause = C;
9816 if (ReductionClause)
9817 break;
9818 continue;
9819 }
9820 }
9821 if (ReductionClause && NogroupClause) {
9822 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
9823 << SourceRange(NogroupClause->getBeginLoc(),
9824 NogroupClause->getEndLoc());
9825 return true;
9826 }
9827 return false;
9828}
9829
9830StmtResult Sema::ActOnOpenMPTaskLoopDirective(
9831 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9832 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9833 if (!AStmt)
9834 return StmtError();
9835
9836 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9836, __PRETTY_FUNCTION__))
;
9837 OMPLoopDirective::HelperExprs B;
9838 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9839 // define the nested loops number.
9840 unsigned NestedLoopCount =
9841 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
9842 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9843 VarsWithImplicitDSA, B);
9844 if (NestedLoopCount == 0)
9845 return StmtError();
9846
9847 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9848, __PRETTY_FUNCTION__))
9848 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9848, __PRETTY_FUNCTION__))
;
9849
9850 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9851 // The grainsize clause and num_tasks clause are mutually exclusive and may
9852 // not appear on the same taskloop directive.
9853 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9854 return StmtError();
9855 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9856 // If a reduction clause is present on the taskloop directive, the nogroup
9857 // clause must not be specified.
9858 if (checkReductionClauseWithNogroup(*this, Clauses))
9859 return StmtError();
9860
9861 setFunctionHasBranchProtectedScope();
9862 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9863 NestedLoopCount, Clauses, AStmt, B,
9864 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9865}
9866
9867StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
9868 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9869 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9870 if (!AStmt)
9871 return StmtError();
9872
9873 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9873, __PRETTY_FUNCTION__))
;
9874 OMPLoopDirective::HelperExprs B;
9875 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9876 // define the nested loops number.
9877 unsigned NestedLoopCount =
9878 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
9879 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9880 VarsWithImplicitDSA, B);
9881 if (NestedLoopCount == 0)
9882 return StmtError();
9883
9884 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9885, __PRETTY_FUNCTION__))
9885 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9885, __PRETTY_FUNCTION__))
;
9886
9887 if (!CurContext->isDependentContext()) {
9888 // Finalize the clauses that need pre-built expressions for CodeGen.
9889 for (OMPClause *C : Clauses) {
9890 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9891 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9892 B.NumIterations, *this, CurScope,
9893 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9894 return StmtError();
9895 }
9896 }
9897
9898 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9899 // The grainsize clause and num_tasks clause are mutually exclusive and may
9900 // not appear on the same taskloop directive.
9901 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9902 return StmtError();
9903 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9904 // If a reduction clause is present on the taskloop directive, the nogroup
9905 // clause must not be specified.
9906 if (checkReductionClauseWithNogroup(*this, Clauses))
9907 return StmtError();
9908 if (checkSimdlenSafelenSpecified(*this, Clauses))
9909 return StmtError();
9910
9911 setFunctionHasBranchProtectedScope();
9912 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
9913 NestedLoopCount, Clauses, AStmt, B);
9914}
9915
9916StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
9917 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9918 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9919 if (!AStmt)
9920 return StmtError();
9921
9922 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9922, __PRETTY_FUNCTION__))
;
9923 OMPLoopDirective::HelperExprs B;
9924 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9925 // define the nested loops number.
9926 unsigned NestedLoopCount =
9927 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
9928 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9929 VarsWithImplicitDSA, B);
9930 if (NestedLoopCount == 0)
9931 return StmtError();
9932
9933 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9934, __PRETTY_FUNCTION__))
9934 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9934, __PRETTY_FUNCTION__))
;
9935
9936 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9937 // The grainsize clause and num_tasks clause are mutually exclusive and may
9938 // not appear on the same taskloop directive.
9939 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9940 return StmtError();
9941 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9942 // If a reduction clause is present on the taskloop directive, the nogroup
9943 // clause must not be specified.
9944 if (checkReductionClauseWithNogroup(*this, Clauses))
9945 return StmtError();
9946
9947 setFunctionHasBranchProtectedScope();
9948 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9949 NestedLoopCount, Clauses, AStmt, B,
9950 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
9951}
9952
9953StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
9954 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9955 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9956 if (!AStmt)
9957 return StmtError();
9958
9959 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9959, __PRETTY_FUNCTION__))
;
9960 OMPLoopDirective::HelperExprs B;
9961 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9962 // define the nested loops number.
9963 unsigned NestedLoopCount =
9964 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
9965 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
9966 VarsWithImplicitDSA, B);
9967 if (NestedLoopCount == 0)
9968 return StmtError();
9969
9970 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9971, __PRETTY_FUNCTION__))
9971 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 9971, __PRETTY_FUNCTION__))
;
9972
9973 if (!CurContext->isDependentContext()) {
9974 // Finalize the clauses that need pre-built expressions for CodeGen.
9975 for (OMPClause *C : Clauses) {
9976 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9978 B.NumIterations, *this, CurScope,
9979 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
9980 return StmtError();
9981 }
9982 }
9983
9984 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9985 // The grainsize clause and num_tasks clause are mutually exclusive and may
9986 // not appear on the same taskloop directive.
9987 if (checkGrainsizeNumTasksClauses(*this, Clauses))
9988 return StmtError();
9989 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9990 // If a reduction clause is present on the taskloop directive, the nogroup
9991 // clause must not be specified.
9992 if (checkReductionClauseWithNogroup(*this, Clauses))
9993 return StmtError();
9994 if (checkSimdlenSafelenSpecified(*this, Clauses))
9995 return StmtError();
9996
9997 setFunctionHasBranchProtectedScope();
9998 return OMPMasterTaskLoopSimdDirective::Create(
9999 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10000}
10001
10002StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10003 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10004 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10005 if (!AStmt)
10006 return StmtError();
10007
10008 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10008, __PRETTY_FUNCTION__))
;
10009 auto *CS = cast<CapturedStmt>(AStmt);
10010 // 1.2.2 OpenMP Language Terminology
10011 // Structured block - An executable statement with a single entry at the
10012 // top and a single exit at the bottom.
10013 // The point of exit cannot be a branch out of the structured block.
10014 // longjmp() and throw() must not violate the entry/exit criteria.
10015 CS->getCapturedDecl()->setNothrow();
10016 for (int ThisCaptureLevel =
10017 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10018 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10019 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10020 // 1.2.2 OpenMP Language Terminology
10021 // Structured block - An executable statement with a single entry at the
10022 // top and a single exit at the bottom.
10023 // The point of exit cannot be a branch out of the structured block.
10024 // longjmp() and throw() must not violate the entry/exit criteria.
10025 CS->getCapturedDecl()->setNothrow();
10026 }
10027
10028 OMPLoopDirective::HelperExprs B;
10029 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10030 // define the nested loops number.
10031 unsigned NestedLoopCount = checkOpenMPLoop(
10032 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10033 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10034 VarsWithImplicitDSA, B);
10035 if (NestedLoopCount == 0)
10036 return StmtError();
10037
10038 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10039, __PRETTY_FUNCTION__))
10039 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10039, __PRETTY_FUNCTION__))
;
10040
10041 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10042 // The grainsize clause and num_tasks clause are mutually exclusive and may
10043 // not appear on the same taskloop directive.
10044 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10045 return StmtError();
10046 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10047 // If a reduction clause is present on the taskloop directive, the nogroup
10048 // clause must not be specified.
10049 if (checkReductionClauseWithNogroup(*this, Clauses))
10050 return StmtError();
10051
10052 setFunctionHasBranchProtectedScope();
10053 return OMPParallelMasterTaskLoopDirective::Create(
10054 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10055 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10056}
10057
10058StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10059 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10060 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10061 if (!AStmt)
10062 return StmtError();
10063
10064 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10064, __PRETTY_FUNCTION__))
;
10065 auto *CS = cast<CapturedStmt>(AStmt);
10066 // 1.2.2 OpenMP Language Terminology
10067 // Structured block - An executable statement with a single entry at the
10068 // top and a single exit at the bottom.
10069 // The point of exit cannot be a branch out of the structured block.
10070 // longjmp() and throw() must not violate the entry/exit criteria.
10071 CS->getCapturedDecl()->setNothrow();
10072 for (int ThisCaptureLevel =
10073 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10074 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10075 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10076 // 1.2.2 OpenMP Language Terminology
10077 // Structured block - An executable statement with a single entry at the
10078 // top and a single exit at the bottom.
10079 // The point of exit cannot be a branch out of the structured block.
10080 // longjmp() and throw() must not violate the entry/exit criteria.
10081 CS->getCapturedDecl()->setNothrow();
10082 }
10083
10084 OMPLoopDirective::HelperExprs B;
10085 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10086 // define the nested loops number.
10087 unsigned NestedLoopCount = checkOpenMPLoop(
10088 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10089 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10090 VarsWithImplicitDSA, B);
10091 if (NestedLoopCount == 0)
10092 return StmtError();
10093
10094 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10095, __PRETTY_FUNCTION__))
10095 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10095, __PRETTY_FUNCTION__))
;
10096
10097 if (!CurContext->isDependentContext()) {
10098 // Finalize the clauses that need pre-built expressions for CodeGen.
10099 for (OMPClause *C : Clauses) {
10100 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10102 B.NumIterations, *this, CurScope,
10103 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10104 return StmtError();
10105 }
10106 }
10107
10108 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10109 // The grainsize clause and num_tasks clause are mutually exclusive and may
10110 // not appear on the same taskloop directive.
10111 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10112 return StmtError();
10113 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10114 // If a reduction clause is present on the taskloop directive, the nogroup
10115 // clause must not be specified.
10116 if (checkReductionClauseWithNogroup(*this, Clauses))
10117 return StmtError();
10118 if (checkSimdlenSafelenSpecified(*this, Clauses))
10119 return StmtError();
10120
10121 setFunctionHasBranchProtectedScope();
10122 return OMPParallelMasterTaskLoopSimdDirective::Create(
10123 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10124}
10125
10126StmtResult Sema::ActOnOpenMPDistributeDirective(
10127 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10128 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10129 if (!AStmt)
10130 return StmtError();
10131
10132 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10132, __PRETTY_FUNCTION__))
;
10133 OMPLoopDirective::HelperExprs B;
10134 // In presence of clause 'collapse' with number of loops, it will
10135 // define the nested loops number.
10136 unsigned NestedLoopCount =
10137 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
10138 nullptr /*ordered not a clause on distribute*/, AStmt,
10139 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10140 if (NestedLoopCount == 0)
10141 return StmtError();
10142
10143 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10144, __PRETTY_FUNCTION__))
10144 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10144, __PRETTY_FUNCTION__))
;
10145
10146 setFunctionHasBranchProtectedScope();
10147 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
10148 NestedLoopCount, Clauses, AStmt, B);
10149}
10150
10151StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
10152 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10153 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10154 if (!AStmt)
10155 return StmtError();
10156
10157 auto *CS = cast<CapturedStmt>(AStmt);
10158 // 1.2.2 OpenMP Language Terminology
10159 // Structured block - An executable statement with a single entry at the
10160 // top and a single exit at the bottom.
10161 // The point of exit cannot be a branch out of the structured block.
10162 // longjmp() and throw() must not violate the entry/exit criteria.
10163 CS->getCapturedDecl()->setNothrow();
10164 for (int ThisCaptureLevel =
10165 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
10166 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10167 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10168 // 1.2.2 OpenMP Language Terminology
10169 // Structured block - An executable statement with a single entry at the
10170 // top and a single exit at the bottom.
10171 // The point of exit cannot be a branch out of the structured block.
10172 // longjmp() and throw() must not violate the entry/exit criteria.
10173 CS->getCapturedDecl()->setNothrow();
10174 }
10175
10176 OMPLoopDirective::HelperExprs B;
10177 // In presence of clause 'collapse' with number of loops, it will
10178 // define the nested loops number.
10179 unsigned NestedLoopCount = checkOpenMPLoop(
10180 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10181 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10182 VarsWithImplicitDSA, B);
10183 if (NestedLoopCount == 0)
10184 return StmtError();
10185
10186 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10187, __PRETTY_FUNCTION__))
10187 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10187, __PRETTY_FUNCTION__))
;
10188
10189 setFunctionHasBranchProtectedScope();
10190 return OMPDistributeParallelForDirective::Create(
10191 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10192 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10193}
10194
10195StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
10196 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10197 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10198 if (!AStmt)
10199 return StmtError();
10200
10201 auto *CS = cast<CapturedStmt>(AStmt);
10202 // 1.2.2 OpenMP Language Terminology
10203 // Structured block - An executable statement with a single entry at the
10204 // top and a single exit at the bottom.
10205 // The point of exit cannot be a branch out of the structured block.
10206 // longjmp() and throw() must not violate the entry/exit criteria.
10207 CS->getCapturedDecl()->setNothrow();
10208 for (int ThisCaptureLevel =
10209 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10210 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10211 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10212 // 1.2.2 OpenMP Language Terminology
10213 // Structured block - An executable statement with a single entry at the
10214 // top and a single exit at the bottom.
10215 // The point of exit cannot be a branch out of the structured block.
10216 // longjmp() and throw() must not violate the entry/exit criteria.
10217 CS->getCapturedDecl()->setNothrow();
10218 }
10219
10220 OMPLoopDirective::HelperExprs B;
10221 // In presence of clause 'collapse' with number of loops, it will
10222 // define the nested loops number.
10223 unsigned NestedLoopCount = checkOpenMPLoop(
10224 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10225 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10226 VarsWithImplicitDSA, B);
10227 if (NestedLoopCount == 0)
10228 return StmtError();
10229
10230 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10231, __PRETTY_FUNCTION__))
10231 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10231, __PRETTY_FUNCTION__))
;
10232
10233 if (!CurContext->isDependentContext()) {
10234 // Finalize the clauses that need pre-built expressions for CodeGen.
10235 for (OMPClause *C : Clauses) {
10236 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10237 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10238 B.NumIterations, *this, CurScope,
10239 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10240 return StmtError();
10241 }
10242 }
10243
10244 if (checkSimdlenSafelenSpecified(*this, Clauses))
10245 return StmtError();
10246
10247 setFunctionHasBranchProtectedScope();
10248 return OMPDistributeParallelForSimdDirective::Create(
10249 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10250}
10251
10252StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
10253 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10254 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10255 if (!AStmt)
10256 return StmtError();
10257
10258 auto *CS = cast<CapturedStmt>(AStmt);
10259 // 1.2.2 OpenMP Language Terminology
10260 // Structured block - An executable statement with a single entry at the
10261 // top and a single exit at the bottom.
10262 // The point of exit cannot be a branch out of the structured block.
10263 // longjmp() and throw() must not violate the entry/exit criteria.
10264 CS->getCapturedDecl()->setNothrow();
10265 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
10266 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10267 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10268 // 1.2.2 OpenMP Language Terminology
10269 // Structured block - An executable statement with a single entry at the
10270 // top and a single exit at the bottom.
10271 // The point of exit cannot be a branch out of the structured block.
10272 // longjmp() and throw() must not violate the entry/exit criteria.
10273 CS->getCapturedDecl()->setNothrow();
10274 }
10275
10276 OMPLoopDirective::HelperExprs B;
10277 // In presence of clause 'collapse' with number of loops, it will
10278 // define the nested loops number.
10279 unsigned NestedLoopCount =
10280 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
10281 nullptr /*ordered not a clause on distribute*/, CS, *this,
10282 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10283 if (NestedLoopCount == 0)
10284 return StmtError();
10285
10286 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10287, __PRETTY_FUNCTION__))
10287 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10287, __PRETTY_FUNCTION__))
;
10288
10289 if (!CurContext->isDependentContext()) {
10290 // Finalize the clauses that need pre-built expressions for CodeGen.
10291 for (OMPClause *C : Clauses) {
10292 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10293 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10294 B.NumIterations, *this, CurScope,
10295 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10296 return StmtError();
10297 }
10298 }
10299
10300 if (checkSimdlenSafelenSpecified(*this, Clauses))
10301 return StmtError();
10302
10303 setFunctionHasBranchProtectedScope();
10304 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
10305 NestedLoopCount, Clauses, AStmt, B);
10306}
10307
10308StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
10309 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10310 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10311 if (!AStmt)
10312 return StmtError();
10313
10314 auto *CS = cast<CapturedStmt>(AStmt);
10315 // 1.2.2 OpenMP Language Terminology
10316 // Structured block - An executable statement with a single entry at the
10317 // top and a single exit at the bottom.
10318 // The point of exit cannot be a branch out of the structured block.
10319 // longjmp() and throw() must not violate the entry/exit criteria.
10320 CS->getCapturedDecl()->setNothrow();
10321 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10322 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10323 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10324 // 1.2.2 OpenMP Language Terminology
10325 // Structured block - An executable statement with a single entry at the
10326 // top and a single exit at the bottom.
10327 // The point of exit cannot be a branch out of the structured block.
10328 // longjmp() and throw() must not violate the entry/exit criteria.
10329 CS->getCapturedDecl()->setNothrow();
10330 }
10331
10332 OMPLoopDirective::HelperExprs B;
10333 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10334 // define the nested loops number.
10335 unsigned NestedLoopCount = checkOpenMPLoop(
10336 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
10337 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10338 VarsWithImplicitDSA, B);
10339 if (NestedLoopCount == 0)
10340 return StmtError();
10341
10342 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10343, __PRETTY_FUNCTION__))
10343 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10343, __PRETTY_FUNCTION__))
;
10344
10345 if (!CurContext->isDependentContext()) {
10346 // Finalize the clauses that need pre-built expressions for CodeGen.
10347 for (OMPClause *C : Clauses) {
10348 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10349 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10350 B.NumIterations, *this, CurScope,
10351 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10352 return StmtError();
10353 }
10354 }
10355 if (checkSimdlenSafelenSpecified(*this, Clauses))
10356 return StmtError();
10357
10358 setFunctionHasBranchProtectedScope();
10359 return OMPTargetParallelForSimdDirective::Create(
10360 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10361}
10362
10363StmtResult Sema::ActOnOpenMPTargetSimdDirective(
10364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10366 if (!AStmt)
10367 return StmtError();
10368
10369 auto *CS = cast<CapturedStmt>(AStmt);
10370 // 1.2.2 OpenMP Language Terminology
10371 // Structured block - An executable statement with a single entry at the
10372 // top and a single exit at the bottom.
10373 // The point of exit cannot be a branch out of the structured block.
10374 // longjmp() and throw() must not violate the entry/exit criteria.
10375 CS->getCapturedDecl()->setNothrow();
10376 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
10377 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10378 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10379 // 1.2.2 OpenMP Language Terminology
10380 // Structured block - An executable statement with a single entry at the
10381 // top and a single exit at the bottom.
10382 // The point of exit cannot be a branch out of the structured block.
10383 // longjmp() and throw() must not violate the entry/exit criteria.
10384 CS->getCapturedDecl()->setNothrow();
10385 }
10386
10387 OMPLoopDirective::HelperExprs B;
10388 // In presence of clause 'collapse' with number of loops, it will define the
10389 // nested loops number.
10390 unsigned NestedLoopCount =
10391 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
10392 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10393 VarsWithImplicitDSA, B);
10394 if (NestedLoopCount == 0)
10395 return StmtError();
10396
10397 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10398, __PRETTY_FUNCTION__))
10398 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10398, __PRETTY_FUNCTION__))
;
10399
10400 if (!CurContext->isDependentContext()) {
10401 // Finalize the clauses that need pre-built expressions for CodeGen.
10402 for (OMPClause *C : Clauses) {
10403 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10404 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10405 B.NumIterations, *this, CurScope,
10406 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10407 return StmtError();
10408 }
10409 }
10410
10411 if (checkSimdlenSafelenSpecified(*this, Clauses))
10412 return StmtError();
10413
10414 setFunctionHasBranchProtectedScope();
10415 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
10416 NestedLoopCount, Clauses, AStmt, B);
10417}
10418
10419StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
10420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10422 if (!AStmt)
10423 return StmtError();
10424
10425 auto *CS = cast<CapturedStmt>(AStmt);
10426 // 1.2.2 OpenMP Language Terminology
10427 // Structured block - An executable statement with a single entry at the
10428 // top and a single exit at the bottom.
10429 // The point of exit cannot be a branch out of the structured block.
10430 // longjmp() and throw() must not violate the entry/exit criteria.
10431 CS->getCapturedDecl()->setNothrow();
10432 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
10433 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10434 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10435 // 1.2.2 OpenMP Language Terminology
10436 // Structured block - An executable statement with a single entry at the
10437 // top and a single exit at the bottom.
10438 // The point of exit cannot be a branch out of the structured block.
10439 // longjmp() and throw() must not violate the entry/exit criteria.
10440 CS->getCapturedDecl()->setNothrow();
10441 }
10442
10443 OMPLoopDirective::HelperExprs B;
10444 // In presence of clause 'collapse' with number of loops, it will
10445 // define the nested loops number.
10446 unsigned NestedLoopCount =
10447 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
10448 nullptr /*ordered not a clause on distribute*/, CS, *this,
10449 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10450 if (NestedLoopCount == 0)
10451 return StmtError();
10452
10453 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10454, __PRETTY_FUNCTION__))
10454 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10454, __PRETTY_FUNCTION__))
;
10455
10456 setFunctionHasBranchProtectedScope();
10457
10458 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10459
10460 return OMPTeamsDistributeDirective::Create(
10461 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10462}
10463
10464StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
10465 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10466 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10467 if (!AStmt)
10468 return StmtError();
10469
10470 auto *CS = cast<CapturedStmt>(AStmt);
10471 // 1.2.2 OpenMP Language Terminology
10472 // Structured block - An executable statement with a single entry at the
10473 // top and a single exit at the bottom.
10474 // The point of exit cannot be a branch out of the structured block.
10475 // longjmp() and throw() must not violate the entry/exit criteria.
10476 CS->getCapturedDecl()->setNothrow();
10477 for (int ThisCaptureLevel =
10478 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
10479 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10480 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10481 // 1.2.2 OpenMP Language Terminology
10482 // Structured block - An executable statement with a single entry at the
10483 // top and a single exit at the bottom.
10484 // The point of exit cannot be a branch out of the structured block.
10485 // longjmp() and throw() must not violate the entry/exit criteria.
10486 CS->getCapturedDecl()->setNothrow();
10487 }
10488
10489 OMPLoopDirective::HelperExprs B;
10490 // In presence of clause 'collapse' with number of loops, it will
10491 // define the nested loops number.
10492 unsigned NestedLoopCount = checkOpenMPLoop(
10493 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
10494 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10495 VarsWithImplicitDSA, B);
10496
10497 if (NestedLoopCount == 0)
10498 return StmtError();
10499
10500 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10501, __PRETTY_FUNCTION__))
10501 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10501, __PRETTY_FUNCTION__))
;
10502
10503 if (!CurContext->isDependentContext()) {
10504 // Finalize the clauses that need pre-built expressions for CodeGen.
10505 for (OMPClause *C : Clauses) {
10506 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10507 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10508 B.NumIterations, *this, CurScope,
10509 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10510 return StmtError();
10511 }
10512 }
10513
10514 if (checkSimdlenSafelenSpecified(*this, Clauses))
10515 return StmtError();
10516
10517 setFunctionHasBranchProtectedScope();
10518
10519 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10520
10521 return OMPTeamsDistributeSimdDirective::Create(
10522 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10523}
10524
10525StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
10526 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10527 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10528 if (!AStmt)
10529 return StmtError();
10530
10531 auto *CS = cast<CapturedStmt>(AStmt);
10532 // 1.2.2 OpenMP Language Terminology
10533 // Structured block - An executable statement with a single entry at the
10534 // top and a single exit at the bottom.
10535 // The point of exit cannot be a branch out of the structured block.
10536 // longjmp() and throw() must not violate the entry/exit criteria.
10537 CS->getCapturedDecl()->setNothrow();
10538
10539 for (int ThisCaptureLevel =
10540 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
10541 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10542 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10543 // 1.2.2 OpenMP Language Terminology
10544 // Structured block - An executable statement with a single entry at the
10545 // top and a single exit at the bottom.
10546 // The point of exit cannot be a branch out of the structured block.
10547 // longjmp() and throw() must not violate the entry/exit criteria.
10548 CS->getCapturedDecl()->setNothrow();
10549 }
10550
10551 OMPLoopDirective::HelperExprs B;
10552 // In presence of clause 'collapse' with number of loops, it will
10553 // define the nested loops number.
10554 unsigned NestedLoopCount = checkOpenMPLoop(
10555 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10556 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10557 VarsWithImplicitDSA, B);
10558
10559 if (NestedLoopCount == 0)
10560 return StmtError();
10561
10562 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10563, __PRETTY_FUNCTION__))
10563 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10563, __PRETTY_FUNCTION__))
;
10564
10565 if (!CurContext->isDependentContext()) {
10566 // Finalize the clauses that need pre-built expressions for CodeGen.
10567 for (OMPClause *C : Clauses) {
10568 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10569 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10570 B.NumIterations, *this, CurScope,
10571 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10572 return StmtError();
10573 }
10574 }
10575
10576 if (checkSimdlenSafelenSpecified(*this, Clauses))
10577 return StmtError();
10578
10579 setFunctionHasBranchProtectedScope();
10580
10581 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10582
10583 return OMPTeamsDistributeParallelForSimdDirective::Create(
10584 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10585}
10586
10587StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
10588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10590 if (!AStmt)
10591 return StmtError();
10592
10593 auto *CS = cast<CapturedStmt>(AStmt);
10594 // 1.2.2 OpenMP Language Terminology
10595 // Structured block - An executable statement with a single entry at the
10596 // top and a single exit at the bottom.
10597 // The point of exit cannot be a branch out of the structured block.
10598 // longjmp() and throw() must not violate the entry/exit criteria.
10599 CS->getCapturedDecl()->setNothrow();
10600
10601 for (int ThisCaptureLevel =
10602 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
10603 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10604 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10605 // 1.2.2 OpenMP Language Terminology
10606 // Structured block - An executable statement with a single entry at the
10607 // top and a single exit at the bottom.
10608 // The point of exit cannot be a branch out of the structured block.
10609 // longjmp() and throw() must not violate the entry/exit criteria.
10610 CS->getCapturedDecl()->setNothrow();
10611 }
10612
10613 OMPLoopDirective::HelperExprs B;
10614 // In presence of clause 'collapse' with number of loops, it will
10615 // define the nested loops number.
10616 unsigned NestedLoopCount = checkOpenMPLoop(
10617 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10618 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10619 VarsWithImplicitDSA, B);
10620
10621 if (NestedLoopCount == 0)
10622 return StmtError();
10623
10624 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10625, __PRETTY_FUNCTION__))
10625 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10625, __PRETTY_FUNCTION__))
;
10626
10627 setFunctionHasBranchProtectedScope();
10628
10629 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
10630
10631 return OMPTeamsDistributeParallelForDirective::Create(
10632 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10633 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10634}
10635
10636StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
10637 Stmt *AStmt,
10638 SourceLocation StartLoc,
10639 SourceLocation EndLoc) {
10640 if (!AStmt)
10641 return StmtError();
10642
10643 auto *CS = cast<CapturedStmt>(AStmt);
10644 // 1.2.2 OpenMP Language Terminology
10645 // Structured block - An executable statement with a single entry at the
10646 // top and a single exit at the bottom.
10647 // The point of exit cannot be a branch out of the structured block.
10648 // longjmp() and throw() must not violate the entry/exit criteria.
10649 CS->getCapturedDecl()->setNothrow();
10650
10651 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
10652 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10653 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10654 // 1.2.2 OpenMP Language Terminology
10655 // Structured block - An executable statement with a single entry at the
10656 // top and a single exit at the bottom.
10657 // The point of exit cannot be a branch out of the structured block.
10658 // longjmp() and throw() must not violate the entry/exit criteria.
10659 CS->getCapturedDecl()->setNothrow();
10660 }
10661 setFunctionHasBranchProtectedScope();
10662
10663 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
10664 AStmt);
10665}
10666
10667StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
10668 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10669 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10670 if (!AStmt)
10671 return StmtError();
10672
10673 auto *CS = cast<CapturedStmt>(AStmt);
10674 // 1.2.2 OpenMP Language Terminology
10675 // Structured block - An executable statement with a single entry at the
10676 // top and a single exit at the bottom.
10677 // The point of exit cannot be a branch out of the structured block.
10678 // longjmp() and throw() must not violate the entry/exit criteria.
10679 CS->getCapturedDecl()->setNothrow();
10680 for (int ThisCaptureLevel =
10681 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
10682 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10683 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10684 // 1.2.2 OpenMP Language Terminology
10685 // Structured block - An executable statement with a single entry at the
10686 // top and a single exit at the bottom.
10687 // The point of exit cannot be a branch out of the structured block.
10688 // longjmp() and throw() must not violate the entry/exit criteria.
10689 CS->getCapturedDecl()->setNothrow();
10690 }
10691
10692 OMPLoopDirective::HelperExprs B;
10693 // In presence of clause 'collapse' with number of loops, it will
10694 // define the nested loops number.
10695 unsigned NestedLoopCount = checkOpenMPLoop(
10696 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
10697 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10698 VarsWithImplicitDSA, B);
10699 if (NestedLoopCount == 0)
10700 return StmtError();
10701
10702 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10703, __PRETTY_FUNCTION__))
10703 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10703, __PRETTY_FUNCTION__))
;
10704
10705 setFunctionHasBranchProtectedScope();
10706 return OMPTargetTeamsDistributeDirective::Create(
10707 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10708}
10709
10710StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
10711 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10712 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10713 if (!AStmt)
10714 return StmtError();
10715
10716 auto *CS = cast<CapturedStmt>(AStmt);
10717 // 1.2.2 OpenMP Language Terminology
10718 // Structured block - An executable statement with a single entry at the
10719 // top and a single exit at the bottom.
10720 // The point of exit cannot be a branch out of the structured block.
10721 // longjmp() and throw() must not violate the entry/exit criteria.
10722 CS->getCapturedDecl()->setNothrow();
10723 for (int ThisCaptureLevel =
10724 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
10725 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10726 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10727 // 1.2.2 OpenMP Language Terminology
10728 // Structured block - An executable statement with a single entry at the
10729 // top and a single exit at the bottom.
10730 // The point of exit cannot be a branch out of the structured block.
10731 // longjmp() and throw() must not violate the entry/exit criteria.
10732 CS->getCapturedDecl()->setNothrow();
10733 }
10734
10735 OMPLoopDirective::HelperExprs B;
10736 // In presence of clause 'collapse' with number of loops, it will
10737 // define the nested loops number.
10738 unsigned NestedLoopCount = checkOpenMPLoop(
10739 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10740 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10741 VarsWithImplicitDSA, B);
10742 if (NestedLoopCount == 0)
10743 return StmtError();
10744
10745 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10746, __PRETTY_FUNCTION__))
10746 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10746, __PRETTY_FUNCTION__))
;
10747
10748 if (!CurContext->isDependentContext()) {
10749 // Finalize the clauses that need pre-built expressions for CodeGen.
10750 for (OMPClause *C : Clauses) {
10751 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10753 B.NumIterations, *this, CurScope,
10754 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10755 return StmtError();
10756 }
10757 }
10758
10759 setFunctionHasBranchProtectedScope();
10760 return OMPTargetTeamsDistributeParallelForDirective::Create(
10761 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10762 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
10763}
10764
10765StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
10766 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10767 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10768 if (!AStmt)
10769 return StmtError();
10770
10771 auto *CS = cast<CapturedStmt>(AStmt);
10772 // 1.2.2 OpenMP Language Terminology
10773 // Structured block - An executable statement with a single entry at the
10774 // top and a single exit at the bottom.
10775 // The point of exit cannot be a branch out of the structured block.
10776 // longjmp() and throw() must not violate the entry/exit criteria.
10777 CS->getCapturedDecl()->setNothrow();
10778 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
10779 OMPD_target_teams_distribute_parallel_for_simd);
10780 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10781 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10782 // 1.2.2 OpenMP Language Terminology
10783 // Structured block - An executable statement with a single entry at the
10784 // top and a single exit at the bottom.
10785 // The point of exit cannot be a branch out of the structured block.
10786 // longjmp() and throw() must not violate the entry/exit criteria.
10787 CS->getCapturedDecl()->setNothrow();
10788 }
10789
10790 OMPLoopDirective::HelperExprs B;
10791 // In presence of clause 'collapse' with number of loops, it will
10792 // define the nested loops number.
10793 unsigned NestedLoopCount =
10794 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
10795 getCollapseNumberExpr(Clauses),
10796 nullptr /*ordered not a clause on distribute*/, CS, *this,
10797 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
10798 if (NestedLoopCount == 0)
10799 return StmtError();
10800
10801 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10803, __PRETTY_FUNCTION__))
10802 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10803, __PRETTY_FUNCTION__))
10803 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10803, __PRETTY_FUNCTION__))
;
10804
10805 if (!CurContext->isDependentContext()) {
10806 // Finalize the clauses that need pre-built expressions for CodeGen.
10807 for (OMPClause *C : Clauses) {
10808 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10809 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10810 B.NumIterations, *this, CurScope,
10811 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10812 return StmtError();
10813 }
10814 }
10815
10816 if (checkSimdlenSafelenSpecified(*this, Clauses))
10817 return StmtError();
10818
10819 setFunctionHasBranchProtectedScope();
10820 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
10821 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10822}
10823
10824StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
10825 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10826 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10827 if (!AStmt)
10828 return StmtError();
10829
10830 auto *CS = cast<CapturedStmt>(AStmt);
10831 // 1.2.2 OpenMP Language Terminology
10832 // Structured block - An executable statement with a single entry at the
10833 // top and a single exit at the bottom.
10834 // The point of exit cannot be a branch out of the structured block.
10835 // longjmp() and throw() must not violate the entry/exit criteria.
10836 CS->getCapturedDecl()->setNothrow();
10837 for (int ThisCaptureLevel =
10838 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
10839 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10840 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10841 // 1.2.2 OpenMP Language Terminology
10842 // Structured block - An executable statement with a single entry at the
10843 // top and a single exit at the bottom.
10844 // The point of exit cannot be a branch out of the structured block.
10845 // longjmp() and throw() must not violate the entry/exit criteria.
10846 CS->getCapturedDecl()->setNothrow();
10847 }
10848
10849 OMPLoopDirective::HelperExprs B;
10850 // In presence of clause 'collapse' with number of loops, it will
10851 // define the nested loops number.
10852 unsigned NestedLoopCount = checkOpenMPLoop(
10853 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
10854 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
10855 VarsWithImplicitDSA, B);
10856 if (NestedLoopCount == 0)
10857 return StmtError();
10858
10859 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10860, __PRETTY_FUNCTION__))
10860 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10860, __PRETTY_FUNCTION__))
;
10861
10862 if (!CurContext->isDependentContext()) {
10863 // Finalize the clauses that need pre-built expressions for CodeGen.
10864 for (OMPClause *C : Clauses) {
10865 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10866 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10867 B.NumIterations, *this, CurScope,
10868 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
10869 return StmtError();
10870 }
10871 }
10872
10873 if (checkSimdlenSafelenSpecified(*this, Clauses))
10874 return StmtError();
10875
10876 setFunctionHasBranchProtectedScope();
10877 return OMPTargetTeamsDistributeSimdDirective::Create(
10878 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10879}
10880
10881OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
10882 SourceLocation StartLoc,
10883 SourceLocation LParenLoc,
10884 SourceLocation EndLoc) {
10885 OMPClause *Res = nullptr;
10886 switch (Kind) {
10887 case OMPC_final:
10888 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
10889 break;
10890 case OMPC_num_threads:
10891 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
10892 break;
10893 case OMPC_safelen:
10894 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
10895 break;
10896 case OMPC_simdlen:
10897 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
10898 break;
10899 case OMPC_allocator:
10900 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
10901 break;
10902 case OMPC_collapse:
10903 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
10904 break;
10905 case OMPC_ordered:
10906 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
10907 break;
10908 case OMPC_device:
10909 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
10910 break;
10911 case OMPC_num_teams:
10912 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
10913 break;
10914 case OMPC_thread_limit:
10915 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
10916 break;
10917 case OMPC_priority:
10918 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
10919 break;
10920 case OMPC_grainsize:
10921 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
10922 break;
10923 case OMPC_num_tasks:
10924 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
10925 break;
10926 case OMPC_hint:
10927 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
10928 break;
10929 case OMPC_depobj:
10930 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
10931 break;
10932 case OMPC_if:
10933 case OMPC_default:
10934 case OMPC_proc_bind:
10935 case OMPC_schedule:
10936 case OMPC_private:
10937 case OMPC_firstprivate:
10938 case OMPC_lastprivate:
10939 case OMPC_shared:
10940 case OMPC_reduction:
10941 case OMPC_task_reduction:
10942 case OMPC_in_reduction:
10943 case OMPC_linear:
10944 case OMPC_aligned:
10945 case OMPC_copyin:
10946 case OMPC_copyprivate:
10947 case OMPC_nowait:
10948 case OMPC_untied:
10949 case OMPC_mergeable:
10950 case OMPC_threadprivate:
10951 case OMPC_allocate:
10952 case OMPC_flush:
10953 case OMPC_read:
10954 case OMPC_write:
10955 case OMPC_update:
10956 case OMPC_capture:
10957 case OMPC_seq_cst:
10958 case OMPC_acq_rel:
10959 case OMPC_acquire:
10960 case OMPC_release:
10961 case OMPC_relaxed:
10962 case OMPC_depend:
10963 case OMPC_threads:
10964 case OMPC_simd:
10965 case OMPC_map:
10966 case OMPC_nogroup:
10967 case OMPC_dist_schedule:
10968 case OMPC_defaultmap:
10969 case OMPC_unknown:
10970 case OMPC_uniform:
10971 case OMPC_to:
10972 case OMPC_from:
10973 case OMPC_use_device_ptr:
10974 case OMPC_is_device_ptr:
10975 case OMPC_unified_address:
10976 case OMPC_unified_shared_memory:
10977 case OMPC_reverse_offload:
10978 case OMPC_dynamic_allocators:
10979 case OMPC_atomic_default_mem_order:
10980 case OMPC_device_type:
10981 case OMPC_match:
10982 case OMPC_nontemporal:
10983 case OMPC_order:
10984 case OMPC_destroy:
10985 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 10985)
;
10986 }
10987 return Res;
10988}
10989
10990// An OpenMP directive such as 'target parallel' has two captured regions:
10991// for the 'target' and 'parallel' respectively. This function returns
10992// the region in which to capture expressions associated with a clause.
10993// A return value of OMPD_unknown signifies that the expression should not
10994// be captured.
10995static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
10996 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
10997 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
10998 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
10999 switch (CKind) {
11000 case OMPC_if:
11001 switch (DKind) {
11002 case OMPD_target_parallel_for_simd:
11003 if (OpenMPVersion >= 50 &&
11004 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11005 CaptureRegion = OMPD_parallel;
11006 break;
11007 }
11008 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11009 case OMPD_target_parallel:
11010 case OMPD_target_parallel_for:
11011 // If this clause applies to the nested 'parallel' region, capture within
11012 // the 'target' region, otherwise do not capture.
11013 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11014 CaptureRegion = OMPD_target;
11015 break;
11016 case OMPD_target_teams_distribute_parallel_for_simd:
11017 if (OpenMPVersion >= 50 &&
11018 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11019 CaptureRegion = OMPD_parallel;
11020 break;
11021 }
11022 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11023 case OMPD_target_teams_distribute_parallel_for:
11024 // If this clause applies to the nested 'parallel' region, capture within
11025 // the 'teams' region, otherwise do not capture.
11026 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11027 CaptureRegion = OMPD_teams;
11028 break;
11029 case OMPD_teams_distribute_parallel_for_simd:
11030 if (OpenMPVersion >= 50 &&
11031 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11032 CaptureRegion = OMPD_parallel;
11033 break;
11034 }
11035 LLVM_FALLTHROUGH[[gnu::fallthrough]];
11036 case OMPD_teams_distribute_parallel_for:
11037 CaptureRegion = OMPD_teams;
11038 break;
11039 case OMPD_target_update:
11040 case OMPD_target_enter_data:
11041 case OMPD_target_exit_data:
11042 CaptureRegion = OMPD_task;
11043 break;
11044 case OMPD_parallel_master_taskloop:
11045 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11046 CaptureRegion = OMPD_parallel;
11047 break;
11048 case OMPD_parallel_master_taskloop_simd:
11049 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11050 NameModifier == OMPD_taskloop) {
11051 CaptureRegion = OMPD_parallel;
11052 break;
11053 }
11054 if (OpenMPVersion <= 45)
11055 break;
11056 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11057 CaptureRegion = OMPD_taskloop;
11058 break;
11059 case OMPD_parallel_for_simd:
11060 if (OpenMPVersion <= 45)
11061 break;
11062 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11063 CaptureRegion = OMPD_parallel;
11064 break;
11065 case OMPD_taskloop_simd:
11066 case OMPD_master_taskloop_simd:
11067 if (OpenMPVersion <= 45)
11068 break;
11069 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11070 CaptureRegion = OMPD_taskloop;
11071 break;
11072 case OMPD_distribute_parallel_for_simd:
11073 if (OpenMPVersion <= 45)
11074 break;
11075 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11076 CaptureRegion = OMPD_parallel;
11077 break;
11078 case OMPD_target_simd:
11079 if (OpenMPVersion >= 50 &&
11080 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11081 CaptureRegion = OMPD_target;
11082 break;
11083 case OMPD_teams_distribute_simd:
11084 case OMPD_target_teams_distribute_simd:
11085 if (OpenMPVersion >= 50 &&
11086 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11087 CaptureRegion = OMPD_teams;
11088 break;
11089 case OMPD_cancel:
11090 case OMPD_parallel:
11091 case OMPD_parallel_master:
11092 case OMPD_parallel_sections:
11093 case OMPD_parallel_for:
11094 case OMPD_target:
11095 case OMPD_target_teams:
11096 case OMPD_target_teams_distribute:
11097 case OMPD_distribute_parallel_for:
11098 case OMPD_task:
11099 case OMPD_taskloop:
11100 case OMPD_master_taskloop:
11101 case OMPD_target_data:
11102 case OMPD_simd:
11103 case OMPD_for_simd:
11104 case OMPD_distribute_simd:
11105 // Do not capture if-clause expressions.
11106 break;
11107 case OMPD_threadprivate:
11108 case OMPD_allocate:
11109 case OMPD_taskyield:
11110 case OMPD_barrier:
11111 case OMPD_taskwait:
11112 case OMPD_cancellation_point:
11113 case OMPD_flush:
11114 case OMPD_depobj:
11115 case OMPD_declare_reduction:
11116 case OMPD_declare_mapper:
11117 case OMPD_declare_simd:
11118 case OMPD_declare_variant:
11119 case OMPD_declare_target:
11120 case OMPD_end_declare_target:
11121 case OMPD_teams:
11122 case OMPD_for:
11123 case OMPD_sections:
11124 case OMPD_section:
11125 case OMPD_single:
11126 case OMPD_master:
11127 case OMPD_critical:
11128 case OMPD_taskgroup:
11129 case OMPD_distribute:
11130 case OMPD_ordered:
11131 case OMPD_atomic:
11132 case OMPD_teams_distribute:
11133 case OMPD_requires:
11134 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11134)
;
11135 case OMPD_unknown:
11136 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11136)
;
11137 }
11138 break;
11139 case OMPC_num_threads:
11140 switch (DKind) {
11141 case OMPD_target_parallel:
11142 case OMPD_target_parallel_for:
11143 case OMPD_target_parallel_for_simd:
11144 CaptureRegion = OMPD_target;
11145 break;
11146 case OMPD_teams_distribute_parallel_for:
11147 case OMPD_teams_distribute_parallel_for_simd:
11148 case OMPD_target_teams_distribute_parallel_for:
11149 case OMPD_target_teams_distribute_parallel_for_simd:
11150 CaptureRegion = OMPD_teams;
11151 break;
11152 case OMPD_parallel:
11153 case OMPD_parallel_master:
11154 case OMPD_parallel_sections:
11155 case OMPD_parallel_for:
11156 case OMPD_parallel_for_simd:
11157 case OMPD_distribute_parallel_for:
11158 case OMPD_distribute_parallel_for_simd:
11159 case OMPD_parallel_master_taskloop:
11160 case OMPD_parallel_master_taskloop_simd:
11161 // Do not capture num_threads-clause expressions.
11162 break;
11163 case OMPD_target_data:
11164 case OMPD_target_enter_data:
11165 case OMPD_target_exit_data:
11166 case OMPD_target_update:
11167 case OMPD_target:
11168 case OMPD_target_simd:
11169 case OMPD_target_teams:
11170 case OMPD_target_teams_distribute:
11171 case OMPD_target_teams_distribute_simd:
11172 case OMPD_cancel:
11173 case OMPD_task:
11174 case OMPD_taskloop:
11175 case OMPD_taskloop_simd:
11176 case OMPD_master_taskloop:
11177 case OMPD_master_taskloop_simd:
11178 case OMPD_threadprivate:
11179 case OMPD_allocate:
11180 case OMPD_taskyield:
11181 case OMPD_barrier:
11182 case OMPD_taskwait:
11183 case OMPD_cancellation_point:
11184 case OMPD_flush:
11185 case OMPD_depobj:
11186 case OMPD_declare_reduction:
11187 case OMPD_declare_mapper:
11188 case OMPD_declare_simd:
11189 case OMPD_declare_variant:
11190 case OMPD_declare_target:
11191 case OMPD_end_declare_target:
11192 case OMPD_teams:
11193 case OMPD_simd:
11194 case OMPD_for:
11195 case OMPD_for_simd:
11196 case OMPD_sections:
11197 case OMPD_section:
11198 case OMPD_single:
11199 case OMPD_master:
11200 case OMPD_critical:
11201 case OMPD_taskgroup:
11202 case OMPD_distribute:
11203 case OMPD_ordered:
11204 case OMPD_atomic:
11205 case OMPD_distribute_simd:
11206 case OMPD_teams_distribute:
11207 case OMPD_teams_distribute_simd:
11208 case OMPD_requires:
11209 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11209)
;
11210 case OMPD_unknown:
11211 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11211)
;
11212 }
11213 break;
11214 case OMPC_num_teams:
11215 switch (DKind) {
11216 case OMPD_target_teams:
11217 case OMPD_target_teams_distribute:
11218 case OMPD_target_teams_distribute_simd:
11219 case OMPD_target_teams_distribute_parallel_for:
11220 case OMPD_target_teams_distribute_parallel_for_simd:
11221 CaptureRegion = OMPD_target;
11222 break;
11223 case OMPD_teams_distribute_parallel_for:
11224 case OMPD_teams_distribute_parallel_for_simd:
11225 case OMPD_teams:
11226 case OMPD_teams_distribute:
11227 case OMPD_teams_distribute_simd:
11228 // Do not capture num_teams-clause expressions.
11229 break;
11230 case OMPD_distribute_parallel_for:
11231 case OMPD_distribute_parallel_for_simd:
11232 case OMPD_task:
11233 case OMPD_taskloop:
11234 case OMPD_taskloop_simd:
11235 case OMPD_master_taskloop:
11236 case OMPD_master_taskloop_simd:
11237 case OMPD_parallel_master_taskloop:
11238 case OMPD_parallel_master_taskloop_simd:
11239 case OMPD_target_data:
11240 case OMPD_target_enter_data:
11241 case OMPD_target_exit_data:
11242 case OMPD_target_update:
11243 case OMPD_cancel:
11244 case OMPD_parallel:
11245 case OMPD_parallel_master:
11246 case OMPD_parallel_sections:
11247 case OMPD_parallel_for:
11248 case OMPD_parallel_for_simd:
11249 case OMPD_target:
11250 case OMPD_target_simd:
11251 case OMPD_target_parallel:
11252 case OMPD_target_parallel_for:
11253 case OMPD_target_parallel_for_simd:
11254 case OMPD_threadprivate:
11255 case OMPD_allocate:
11256 case OMPD_taskyield:
11257 case OMPD_barrier:
11258 case OMPD_taskwait:
11259 case OMPD_cancellation_point:
11260 case OMPD_flush:
11261 case OMPD_depobj:
11262 case OMPD_declare_reduction:
11263 case OMPD_declare_mapper:
11264 case OMPD_declare_simd:
11265 case OMPD_declare_variant:
11266 case OMPD_declare_target:
11267 case OMPD_end_declare_target:
11268 case OMPD_simd:
11269 case OMPD_for:
11270 case OMPD_for_simd:
11271 case OMPD_sections:
11272 case OMPD_section:
11273 case OMPD_single:
11274 case OMPD_master:
11275 case OMPD_critical:
11276 case OMPD_taskgroup:
11277 case OMPD_distribute:
11278 case OMPD_ordered:
11279 case OMPD_atomic:
11280 case OMPD_distribute_simd:
11281 case OMPD_requires:
11282 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11282)
;
11283 case OMPD_unknown:
11284 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11284)
;
11285 }
11286 break;
11287 case OMPC_thread_limit:
11288 switch (DKind) {
11289 case OMPD_target_teams:
11290 case OMPD_target_teams_distribute:
11291 case OMPD_target_teams_distribute_simd:
11292 case OMPD_target_teams_distribute_parallel_for:
11293 case OMPD_target_teams_distribute_parallel_for_simd:
11294 CaptureRegion = OMPD_target;
11295 break;
11296 case OMPD_teams_distribute_parallel_for:
11297 case OMPD_teams_distribute_parallel_for_simd:
11298 case OMPD_teams:
11299 case OMPD_teams_distribute:
11300 case OMPD_teams_distribute_simd:
11301 // Do not capture thread_limit-clause expressions.
11302 break;
11303 case OMPD_distribute_parallel_for:
11304 case OMPD_distribute_parallel_for_simd:
11305 case OMPD_task:
11306 case OMPD_taskloop:
11307 case OMPD_taskloop_simd:
11308 case OMPD_master_taskloop:
11309 case OMPD_master_taskloop_simd:
11310 case OMPD_parallel_master_taskloop:
11311 case OMPD_parallel_master_taskloop_simd:
11312 case OMPD_target_data:
11313 case OMPD_target_enter_data:
11314 case OMPD_target_exit_data:
11315 case OMPD_target_update:
11316 case OMPD_cancel:
11317 case OMPD_parallel:
11318 case OMPD_parallel_master:
11319 case OMPD_parallel_sections:
11320 case OMPD_parallel_for:
11321 case OMPD_parallel_for_simd:
11322 case OMPD_target:
11323 case OMPD_target_simd:
11324 case OMPD_target_parallel:
11325 case OMPD_target_parallel_for:
11326 case OMPD_target_parallel_for_simd:
11327 case OMPD_threadprivate:
11328 case OMPD_allocate:
11329 case OMPD_taskyield:
11330 case OMPD_barrier:
11331 case OMPD_taskwait:
11332 case OMPD_cancellation_point:
11333 case OMPD_flush:
11334 case OMPD_depobj:
11335 case OMPD_declare_reduction:
11336 case OMPD_declare_mapper:
11337 case OMPD_declare_simd:
11338 case OMPD_declare_variant:
11339 case OMPD_declare_target:
11340 case OMPD_end_declare_target:
11341 case OMPD_simd:
11342 case OMPD_for:
11343 case OMPD_for_simd:
11344 case OMPD_sections:
11345 case OMPD_section:
11346 case OMPD_single:
11347 case OMPD_master:
11348 case OMPD_critical:
11349 case OMPD_taskgroup:
11350 case OMPD_distribute:
11351 case OMPD_ordered:
11352 case OMPD_atomic:
11353 case OMPD_distribute_simd:
11354 case OMPD_requires:
11355 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11355)
;
11356 case OMPD_unknown:
11357 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11357)
;
11358 }
11359 break;
11360 case OMPC_schedule:
11361 switch (DKind) {
11362 case OMPD_parallel_for:
11363 case OMPD_parallel_for_simd:
11364 case OMPD_distribute_parallel_for:
11365 case OMPD_distribute_parallel_for_simd:
11366 case OMPD_teams_distribute_parallel_for:
11367 case OMPD_teams_distribute_parallel_for_simd:
11368 case OMPD_target_parallel_for:
11369 case OMPD_target_parallel_for_simd:
11370 case OMPD_target_teams_distribute_parallel_for:
11371 case OMPD_target_teams_distribute_parallel_for_simd:
11372 CaptureRegion = OMPD_parallel;
11373 break;
11374 case OMPD_for:
11375 case OMPD_for_simd:
11376 // Do not capture schedule-clause expressions.
11377 break;
11378 case OMPD_task:
11379 case OMPD_taskloop:
11380 case OMPD_taskloop_simd:
11381 case OMPD_master_taskloop:
11382 case OMPD_master_taskloop_simd:
11383 case OMPD_parallel_master_taskloop:
11384 case OMPD_parallel_master_taskloop_simd:
11385 case OMPD_target_data:
11386 case OMPD_target_enter_data:
11387 case OMPD_target_exit_data:
11388 case OMPD_target_update:
11389 case OMPD_teams:
11390 case OMPD_teams_distribute:
11391 case OMPD_teams_distribute_simd:
11392 case OMPD_target_teams_distribute:
11393 case OMPD_target_teams_distribute_simd:
11394 case OMPD_target:
11395 case OMPD_target_simd:
11396 case OMPD_target_parallel:
11397 case OMPD_cancel:
11398 case OMPD_parallel:
11399 case OMPD_parallel_master:
11400 case OMPD_parallel_sections:
11401 case OMPD_threadprivate:
11402 case OMPD_allocate:
11403 case OMPD_taskyield:
11404 case OMPD_barrier:
11405 case OMPD_taskwait:
11406 case OMPD_cancellation_point:
11407 case OMPD_flush:
11408 case OMPD_depobj:
11409 case OMPD_declare_reduction:
11410 case OMPD_declare_mapper:
11411 case OMPD_declare_simd:
11412 case OMPD_declare_variant:
11413 case OMPD_declare_target:
11414 case OMPD_end_declare_target:
11415 case OMPD_simd:
11416 case OMPD_sections:
11417 case OMPD_section:
11418 case OMPD_single:
11419 case OMPD_master:
11420 case OMPD_critical:
11421 case OMPD_taskgroup:
11422 case OMPD_distribute:
11423 case OMPD_ordered:
11424 case OMPD_atomic:
11425 case OMPD_distribute_simd:
11426 case OMPD_target_teams:
11427 case OMPD_requires:
11428 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11428)
;
11429 case OMPD_unknown:
11430 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11430)
;
11431 }
11432 break;
11433 case OMPC_dist_schedule:
11434 switch (DKind) {
11435 case OMPD_teams_distribute_parallel_for:
11436 case OMPD_teams_distribute_parallel_for_simd:
11437 case OMPD_teams_distribute:
11438 case OMPD_teams_distribute_simd:
11439 case OMPD_target_teams_distribute_parallel_for:
11440 case OMPD_target_teams_distribute_parallel_for_simd:
11441 case OMPD_target_teams_distribute:
11442 case OMPD_target_teams_distribute_simd:
11443 CaptureRegion = OMPD_teams;
11444 break;
11445 case OMPD_distribute_parallel_for:
11446 case OMPD_distribute_parallel_for_simd:
11447 case OMPD_distribute:
11448 case OMPD_distribute_simd:
11449 // Do not capture thread_limit-clause expressions.
11450 break;
11451 case OMPD_parallel_for:
11452 case OMPD_parallel_for_simd:
11453 case OMPD_target_parallel_for_simd:
11454 case OMPD_target_parallel_for:
11455 case OMPD_task:
11456 case OMPD_taskloop:
11457 case OMPD_taskloop_simd:
11458 case OMPD_master_taskloop:
11459 case OMPD_master_taskloop_simd:
11460 case OMPD_parallel_master_taskloop:
11461 case OMPD_parallel_master_taskloop_simd:
11462 case OMPD_target_data:
11463 case OMPD_target_enter_data:
11464 case OMPD_target_exit_data:
11465 case OMPD_target_update:
11466 case OMPD_teams:
11467 case OMPD_target:
11468 case OMPD_target_simd:
11469 case OMPD_target_parallel:
11470 case OMPD_cancel:
11471 case OMPD_parallel:
11472 case OMPD_parallel_master:
11473 case OMPD_parallel_sections:
11474 case OMPD_threadprivate:
11475 case OMPD_allocate:
11476 case OMPD_taskyield:
11477 case OMPD_barrier:
11478 case OMPD_taskwait:
11479 case OMPD_cancellation_point:
11480 case OMPD_flush:
11481 case OMPD_depobj:
11482 case OMPD_declare_reduction:
11483 case OMPD_declare_mapper:
11484 case OMPD_declare_simd:
11485 case OMPD_declare_variant:
11486 case OMPD_declare_target:
11487 case OMPD_end_declare_target:
11488 case OMPD_simd:
11489 case OMPD_for:
11490 case OMPD_for_simd:
11491 case OMPD_sections:
11492 case OMPD_section:
11493 case OMPD_single:
11494 case OMPD_master:
11495 case OMPD_critical:
11496 case OMPD_taskgroup:
11497 case OMPD_ordered:
11498 case OMPD_atomic:
11499 case OMPD_target_teams:
11500 case OMPD_requires:
11501 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11501)
;
11502 case OMPD_unknown:
11503 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11503)
;
11504 }
11505 break;
11506 case OMPC_device:
11507 switch (DKind) {
11508 case OMPD_target_update:
11509 case OMPD_target_enter_data:
11510 case OMPD_target_exit_data:
11511 case OMPD_target:
11512 case OMPD_target_simd:
11513 case OMPD_target_teams:
11514 case OMPD_target_parallel:
11515 case OMPD_target_teams_distribute:
11516 case OMPD_target_teams_distribute_simd:
11517 case OMPD_target_parallel_for:
11518 case OMPD_target_parallel_for_simd:
11519 case OMPD_target_teams_distribute_parallel_for:
11520 case OMPD_target_teams_distribute_parallel_for_simd:
11521 CaptureRegion = OMPD_task;
11522 break;
11523 case OMPD_target_data:
11524 // Do not capture device-clause expressions.
11525 break;
11526 case OMPD_teams_distribute_parallel_for:
11527 case OMPD_teams_distribute_parallel_for_simd:
11528 case OMPD_teams:
11529 case OMPD_teams_distribute:
11530 case OMPD_teams_distribute_simd:
11531 case OMPD_distribute_parallel_for:
11532 case OMPD_distribute_parallel_for_simd:
11533 case OMPD_task:
11534 case OMPD_taskloop:
11535 case OMPD_taskloop_simd:
11536 case OMPD_master_taskloop:
11537 case OMPD_master_taskloop_simd:
11538 case OMPD_parallel_master_taskloop:
11539 case OMPD_parallel_master_taskloop_simd:
11540 case OMPD_cancel:
11541 case OMPD_parallel:
11542 case OMPD_parallel_master:
11543 case OMPD_parallel_sections:
11544 case OMPD_parallel_for:
11545 case OMPD_parallel_for_simd:
11546 case OMPD_threadprivate:
11547 case OMPD_allocate:
11548 case OMPD_taskyield:
11549 case OMPD_barrier:
11550 case OMPD_taskwait:
11551 case OMPD_cancellation_point:
11552 case OMPD_flush:
11553 case OMPD_depobj:
11554 case OMPD_declare_reduction:
11555 case OMPD_declare_mapper:
11556 case OMPD_declare_simd:
11557 case OMPD_declare_variant:
11558 case OMPD_declare_target:
11559 case OMPD_end_declare_target:
11560 case OMPD_simd:
11561 case OMPD_for:
11562 case OMPD_for_simd:
11563 case OMPD_sections:
11564 case OMPD_section:
11565 case OMPD_single:
11566 case OMPD_master:
11567 case OMPD_critical:
11568 case OMPD_taskgroup:
11569 case OMPD_distribute:
11570 case OMPD_ordered:
11571 case OMPD_atomic:
11572 case OMPD_distribute_simd:
11573 case OMPD_requires:
11574 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11574)
;
11575 case OMPD_unknown:
11576 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11576)
;
11577 }
11578 break;
11579 case OMPC_grainsize:
11580 case OMPC_num_tasks:
11581 case OMPC_final:
11582 case OMPC_priority:
11583 switch (DKind) {
11584 case OMPD_task:
11585 case OMPD_taskloop:
11586 case OMPD_taskloop_simd:
11587 case OMPD_master_taskloop:
11588 case OMPD_master_taskloop_simd:
11589 break;
11590 case OMPD_parallel_master_taskloop:
11591 case OMPD_parallel_master_taskloop_simd:
11592 CaptureRegion = OMPD_parallel;
11593 break;
11594 case OMPD_target_update:
11595 case OMPD_target_enter_data:
11596 case OMPD_target_exit_data:
11597 case OMPD_target:
11598 case OMPD_target_simd:
11599 case OMPD_target_teams:
11600 case OMPD_target_parallel:
11601 case OMPD_target_teams_distribute:
11602 case OMPD_target_teams_distribute_simd:
11603 case OMPD_target_parallel_for:
11604 case OMPD_target_parallel_for_simd:
11605 case OMPD_target_teams_distribute_parallel_for:
11606 case OMPD_target_teams_distribute_parallel_for_simd:
11607 case OMPD_target_data:
11608 case OMPD_teams_distribute_parallel_for:
11609 case OMPD_teams_distribute_parallel_for_simd:
11610 case OMPD_teams:
11611 case OMPD_teams_distribute:
11612 case OMPD_teams_distribute_simd:
11613 case OMPD_distribute_parallel_for:
11614 case OMPD_distribute_parallel_for_simd:
11615 case OMPD_cancel:
11616 case OMPD_parallel:
11617 case OMPD_parallel_master:
11618 case OMPD_parallel_sections:
11619 case OMPD_parallel_for:
11620 case OMPD_parallel_for_simd:
11621 case OMPD_threadprivate:
11622 case OMPD_allocate:
11623 case OMPD_taskyield:
11624 case OMPD_barrier:
11625 case OMPD_taskwait:
11626 case OMPD_cancellation_point:
11627 case OMPD_flush:
11628 case OMPD_depobj:
11629 case OMPD_declare_reduction:
11630 case OMPD_declare_mapper:
11631 case OMPD_declare_simd:
11632 case OMPD_declare_variant:
11633 case OMPD_declare_target:
11634 case OMPD_end_declare_target:
11635 case OMPD_simd:
11636 case OMPD_for:
11637 case OMPD_for_simd:
11638 case OMPD_sections:
11639 case OMPD_section:
11640 case OMPD_single:
11641 case OMPD_master:
11642 case OMPD_critical:
11643 case OMPD_taskgroup:
11644 case OMPD_distribute:
11645 case OMPD_ordered:
11646 case OMPD_atomic:
11647 case OMPD_distribute_simd:
11648 case OMPD_requires:
11649 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with grainsize-clause"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11649)
;
11650 case OMPD_unknown:
11651 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11651)
;
11652 }
11653 break;
11654 case OMPC_firstprivate:
11655 case OMPC_lastprivate:
11656 case OMPC_reduction:
11657 case OMPC_task_reduction:
11658 case OMPC_in_reduction:
11659 case OMPC_linear:
11660 case OMPC_default:
11661 case OMPC_proc_bind:
11662 case OMPC_safelen:
11663 case OMPC_simdlen:
11664 case OMPC_allocator:
11665 case OMPC_collapse:
11666 case OMPC_private:
11667 case OMPC_shared:
11668 case OMPC_aligned:
11669 case OMPC_copyin:
11670 case OMPC_copyprivate:
11671 case OMPC_ordered:
11672 case OMPC_nowait:
11673 case OMPC_untied:
11674 case OMPC_mergeable:
11675 case OMPC_threadprivate:
11676 case OMPC_allocate:
11677 case OMPC_flush:
11678 case OMPC_depobj:
11679 case OMPC_read:
11680 case OMPC_write:
11681 case OMPC_update:
11682 case OMPC_capture:
11683 case OMPC_seq_cst:
11684 case OMPC_acq_rel:
11685 case OMPC_acquire:
11686 case OMPC_release:
11687 case OMPC_relaxed:
11688 case OMPC_depend:
11689 case OMPC_threads:
11690 case OMPC_simd:
11691 case OMPC_map:
11692 case OMPC_nogroup:
11693 case OMPC_hint:
11694 case OMPC_defaultmap:
11695 case OMPC_unknown:
11696 case OMPC_uniform:
11697 case OMPC_to:
11698 case OMPC_from:
11699 case OMPC_use_device_ptr:
11700 case OMPC_is_device_ptr:
11701 case OMPC_unified_address:
11702 case OMPC_unified_shared_memory:
11703 case OMPC_reverse_offload:
11704 case OMPC_dynamic_allocators:
11705 case OMPC_atomic_default_mem_order:
11706 case OMPC_device_type:
11707 case OMPC_match:
11708 case OMPC_nontemporal:
11709 case OMPC_order:
11710 case OMPC_destroy:
11711 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11711)
;
11712 }
11713 return CaptureRegion;
11714}
11715
11716OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
11717 Expr *Condition, SourceLocation StartLoc,
11718 SourceLocation LParenLoc,
11719 SourceLocation NameModifierLoc,
11720 SourceLocation ColonLoc,
11721 SourceLocation EndLoc) {
11722 Expr *ValExpr = Condition;
11723 Stmt *HelperValStmt = nullptr;
11724 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11725 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11726 !Condition->isInstantiationDependent() &&
11727 !Condition->containsUnexpandedParameterPack()) {
11728 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11729 if (Val.isInvalid())
11730 return nullptr;
11731
11732 ValExpr = Val.get();
11733
11734 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
11735 CaptureRegion = getOpenMPCaptureRegionForClause(
11736 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
11737 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11738 ValExpr = MakeFullExpr(ValExpr).get();
11739 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11740 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11741 HelperValStmt = buildPreInits(Context, Captures);
11742 }
11743 }
11744
11745 return new (Context)
11746 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
11747 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
11748}
11749
11750OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
11751 SourceLocation StartLoc,
11752 SourceLocation LParenLoc,
11753 SourceLocation EndLoc) {
11754 Expr *ValExpr = Condition;
11755 Stmt *HelperValStmt = nullptr;
11756 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11757 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11758 !Condition->isInstantiationDependent() &&
11759 !Condition->containsUnexpandedParameterPack()) {
11760 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11761 if (Val.isInvalid())
11762 return nullptr;
11763
11764 ValExpr = MakeFullExpr(Val.get()).get();
11765
11766 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
11767 CaptureRegion =
11768 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
11769 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11770 ValExpr = MakeFullExpr(ValExpr).get();
11771 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11772 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11773 HelperValStmt = buildPreInits(Context, Captures);
11774 }
11775 }
11776
11777 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
11778 StartLoc, LParenLoc, EndLoc);
11779}
11780
11781ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
11782 Expr *Op) {
11783 if (!Op)
11784 return ExprError();
11785
11786 class IntConvertDiagnoser : public ICEConvertDiagnoser {
11787 public:
11788 IntConvertDiagnoser()
11789 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
11790 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
11791 QualType T) override {
11792 return S.Diag(Loc, diag::err_omp_not_integral) << T;
11793 }
11794 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
11795 QualType T) override {
11796 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
11797 }
11798 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
11799 QualType T,
11800 QualType ConvTy) override {
11801 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
11802 }
11803 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
11804 QualType ConvTy) override {
11805 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11806 << ConvTy->isEnumeralType() << ConvTy;
11807 }
11808 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
11809 QualType T) override {
11810 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
11811 }
11812 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
11813 QualType ConvTy) override {
11814 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11815 << ConvTy->isEnumeralType() << ConvTy;
11816 }
11817 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
11818 QualType) override {
11819 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 11819)
;
11820 }
11821 } ConvertDiagnoser;
11822 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
11823}
11824
11825static bool
11826isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
11827 bool StrictlyPositive, bool BuildCapture = false,
11828 OpenMPDirectiveKind DKind = OMPD_unknown,
11829 OpenMPDirectiveKind *CaptureRegion = nullptr,
11830 Stmt **HelperValStmt = nullptr) {
11831 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
11832 !ValExpr->isInstantiationDependent()) {
11833 SourceLocation Loc = ValExpr->getExprLoc();
11834 ExprResult Value =
11835 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
11836 if (Value.isInvalid())
11837 return false;
11838
11839 ValExpr = Value.get();
11840 // The expression must evaluate to a non-negative integer value.
11841 llvm::APSInt Result;
11842 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
11843 Result.isSigned() &&
11844 !((!StrictlyPositive && Result.isNonNegative()) ||
11845 (StrictlyPositive && Result.isStrictlyPositive()))) {
11846 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
11847 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11848 << ValExpr->getSourceRange();
11849 return false;
11850 }
11851 if (!BuildCapture)
11852 return true;
11853 *CaptureRegion =
11854 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
11855 if (*CaptureRegion != OMPD_unknown &&
11856 !SemaRef.CurContext->isDependentContext()) {
11857 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
11858 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11859 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
11860 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
11861 }
11862 }
11863 return true;
11864}
11865
11866OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
11867 SourceLocation StartLoc,
11868 SourceLocation LParenLoc,
11869 SourceLocation EndLoc) {
11870 Expr *ValExpr = NumThreads;
11871 Stmt *HelperValStmt = nullptr;
11872
11873 // OpenMP [2.5, Restrictions]
11874 // The num_threads expression must evaluate to a positive integer value.
11875 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
11876 /*StrictlyPositive=*/true))
11877 return nullptr;
11878
11879 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
11880 OpenMPDirectiveKind CaptureRegion =
11881 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
11882 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11883 ValExpr = MakeFullExpr(ValExpr).get();
11884 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11885 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11886 HelperValStmt = buildPreInits(Context, Captures);
11887 }
11888
11889 return new (Context) OMPNumThreadsClause(
11890 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
11891}
11892
11893ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
11894 OpenMPClauseKind CKind,
11895 bool StrictlyPositive) {
11896 if (!E)
11897 return ExprError();
11898 if (E->isValueDependent() || E->isTypeDependent() ||
11899 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
11900 return E;
11901 llvm::APSInt Result;
11902 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
11903 if (ICE.isInvalid())
11904 return ExprError();
11905 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
11906 (!StrictlyPositive && !Result.isNonNegative())) {
11907 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
11908 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11909 << E->getSourceRange();
11910 return ExprError();
11911 }
11912 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
11913 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
11914 << E->getSourceRange();
11915 return ExprError();
11916 }
11917 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
11918 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
11919 else if (CKind == OMPC_ordered)
11920 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
11921 return ICE;
11922}
11923
11924OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
11925 SourceLocation LParenLoc,
11926 SourceLocation EndLoc) {
11927 // OpenMP [2.8.1, simd construct, Description]
11928 // The parameter of the safelen clause must be a constant
11929 // positive integer expression.
11930 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
11931 if (Safelen.isInvalid())
11932 return nullptr;
11933 return new (Context)
11934 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
11935}
11936
11937OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
11938 SourceLocation LParenLoc,
11939 SourceLocation EndLoc) {
11940 // OpenMP [2.8.1, simd construct, Description]
11941 // The parameter of the simdlen clause must be a constant
11942 // positive integer expression.
11943 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
11944 if (Simdlen.isInvalid())
11945 return nullptr;
11946 return new (Context)
11947 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
11948}
11949
11950/// Tries to find omp_allocator_handle_t type.
11951static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
11952 DSAStackTy *Stack) {
11953 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
11954 if (!OMPAllocatorHandleT.isNull())
11955 return true;
11956 // Build the predefined allocator expressions.
11957 bool ErrorFound = false;
11958 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
11959 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
11960 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
11961 StringRef Allocator =
11962 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
11963 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
11964 auto *VD = dyn_cast_or_null<ValueDecl>(
11965 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
11966 if (!VD) {
11967 ErrorFound = true;
11968 break;
11969 }
11970 QualType AllocatorType =
11971 VD->getType().getNonLValueExprType(S.getASTContext());
11972 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
11973 if (!Res.isUsable()) {
11974 ErrorFound = true;
11975 break;
11976 }
11977 if (OMPAllocatorHandleT.isNull())
11978 OMPAllocatorHandleT = AllocatorType;
11979 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
11980 ErrorFound = true;
11981 break;
11982 }
11983 Stack->setAllocator(AllocatorKind, Res.get());
11984 }
11985 if (ErrorFound) {
11986 S.Diag(Loc, diag::err_omp_implied_type_not_found)
11987 << "omp_allocator_handle_t";
11988 return false;
11989 }
11990 OMPAllocatorHandleT.addConst();
11991 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
11992 return true;
11993}
11994
11995OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
11996 SourceLocation LParenLoc,
11997 SourceLocation EndLoc) {
11998 // OpenMP [2.11.3, allocate Directive, Description]
11999 // allocator is an expression of omp_allocator_handle_t type.
12000 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
12001 return nullptr;
12002
12003 ExprResult Allocator = DefaultLvalueConversion(A);
12004 if (Allocator.isInvalid())
12005 return nullptr;
12006 Allocator = PerformImplicitConversion(Allocator.get(),
12007 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
12008 Sema::AA_Initializing,
12009 /*AllowExplicit=*/true);
12010 if (Allocator.isInvalid())
12011 return nullptr;
12012 return new (Context)
12013 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12014}
12015
12016OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12017 SourceLocation StartLoc,
12018 SourceLocation LParenLoc,
12019 SourceLocation EndLoc) {
12020 // OpenMP [2.7.1, loop construct, Description]
12021 // OpenMP [2.8.1, simd construct, Description]
12022 // OpenMP [2.9.6, distribute construct, Description]
12023 // The parameter of the collapse clause must be a constant
12024 // positive integer expression.
12025 ExprResult NumForLoopsResult =
12026 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12027 if (NumForLoopsResult.isInvalid())
12028 return nullptr;
12029 return new (Context)
12030 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12031}
12032
12033OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12034 SourceLocation EndLoc,
12035 SourceLocation LParenLoc,
12036 Expr *NumForLoops) {
12037 // OpenMP [2.7.1, loop construct, Description]
12038 // OpenMP [2.8.1, simd construct, Description]
12039 // OpenMP [2.9.6, distribute construct, Description]
12040 // The parameter of the ordered clause must be a constant
12041 // positive integer expression if any.
12042 if (NumForLoops && LParenLoc.isValid()) {
12043 ExprResult NumForLoopsResult =
12044 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12045 if (NumForLoopsResult.isInvalid())
12046 return nullptr;
12047 NumForLoops = NumForLoopsResult.get();
12048 } else {
12049 NumForLoops = nullptr;
12050 }
12051 auto *Clause = OMPOrderedClause::Create(
12052 Context, NumForLoops, NumForLoops ? DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() : 0,
12053 StartLoc, LParenLoc, EndLoc);
12054 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12055 return Clause;
12056}
12057
12058OMPClause *Sema::ActOnOpenMPSimpleClause(
12059 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12060 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12061 OMPClause *Res = nullptr;
12062 switch (Kind) {
12063 case OMPC_default:
12064 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12065 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12066 break;
12067 case OMPC_proc_bind:
12068 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12069 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12070 break;
12071 case OMPC_atomic_default_mem_order:
12072 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12073 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12074 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12075 break;
12076 case OMPC_order:
12077 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
12078 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12079 break;
12080 case OMPC_update:
12081 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
12082 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12083 break;
12084 case OMPC_if:
12085 case OMPC_final:
12086 case OMPC_num_threads:
12087 case OMPC_safelen:
12088 case OMPC_simdlen:
12089 case OMPC_allocator:
12090 case OMPC_collapse:
12091 case OMPC_schedule:
12092 case OMPC_private:
12093 case OMPC_firstprivate:
12094 case OMPC_lastprivate:
12095 case OMPC_shared:
12096 case OMPC_reduction:
12097 case OMPC_task_reduction:
12098 case OMPC_in_reduction:
12099 case OMPC_linear:
12100 case OMPC_aligned:
12101 case OMPC_copyin:
12102 case OMPC_copyprivate:
12103 case OMPC_ordered:
12104 case OMPC_nowait:
12105 case OMPC_untied:
12106 case OMPC_mergeable:
12107 case OMPC_threadprivate:
12108 case OMPC_allocate:
12109 case OMPC_flush:
12110 case OMPC_depobj:
12111 case OMPC_read:
12112 case OMPC_write:
12113 case OMPC_capture:
12114 case OMPC_seq_cst:
12115 case OMPC_acq_rel:
12116 case OMPC_acquire:
12117 case OMPC_release:
12118 case OMPC_relaxed:
12119 case OMPC_depend:
12120 case OMPC_device:
12121 case OMPC_threads:
12122 case OMPC_simd:
12123 case OMPC_map:
12124 case OMPC_num_teams:
12125 case OMPC_thread_limit:
12126 case OMPC_priority:
12127 case OMPC_grainsize:
12128 case OMPC_nogroup:
12129 case OMPC_num_tasks:
12130 case OMPC_hint:
12131 case OMPC_dist_schedule:
12132 case OMPC_defaultmap:
12133 case OMPC_unknown:
12134 case OMPC_uniform:
12135 case OMPC_to:
12136 case OMPC_from:
12137 case OMPC_use_device_ptr:
12138 case OMPC_is_device_ptr:
12139 case OMPC_unified_address:
12140 case OMPC_unified_shared_memory:
12141 case OMPC_reverse_offload:
12142 case OMPC_dynamic_allocators:
12143 case OMPC_device_type:
12144 case OMPC_match:
12145 case OMPC_nontemporal:
12146 case OMPC_destroy:
12147 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12147)
;
12148 }
12149 return Res;
12150}
12151
12152static std::string
12153getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
12154 ArrayRef<unsigned> Exclude = llvm::None) {
12155 SmallString<256> Buffer;
12156 llvm::raw_svector_ostream Out(Buffer);
12157 unsigned Skipped = Exclude.size();
12158 auto S = Exclude.begin(), E = Exclude.end();
12159 for (unsigned I = First; I < Last; ++I) {
12160 if (std::find(S, E, I) != E) {
12161 --Skipped;
12162 continue;
12163 }
12164 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
12165 if (I + Skipped + 2 == Last)
12166 Out << " or ";
12167 else if (I + Skipped + 1 != Last)
12168 Out << ", ";
12169 }
12170 return std::string(Out.str());
12171}
12172
12173OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
12174 SourceLocation KindKwLoc,
12175 SourceLocation StartLoc,
12176 SourceLocation LParenLoc,
12177 SourceLocation EndLoc) {
12178 if (Kind == OMP_DEFAULT_unknown) {
12179 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12180 << getListOfPossibleValues(OMPC_default, /*First=*/0,
12181 /*Last=*/unsigned(OMP_DEFAULT_unknown))
12182 << getOpenMPClauseName(OMPC_default);
12183 return nullptr;
12184 }
12185 if (Kind == OMP_DEFAULT_none)
12186 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
12187 else if (Kind == OMP_DEFAULT_shared)
12188 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
12189
12190 return new (Context)
12191 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
12192}
12193
12194OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
12195 SourceLocation KindKwLoc,
12196 SourceLocation StartLoc,
12197 SourceLocation LParenLoc,
12198 SourceLocation EndLoc) {
12199 if (Kind == OMP_PROC_BIND_unknown) {
12200 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12201 << getListOfPossibleValues(OMPC_proc_bind,
12202 /*First=*/unsigned(OMP_PROC_BIND_master),
12203 /*Last=*/5)
12204 << getOpenMPClauseName(OMPC_proc_bind);
12205 return nullptr;
12206 }
12207 return new (Context)
12208 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
12209}
12210
12211OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
12212 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
12213 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12214 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
12215 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12216 << getListOfPossibleValues(
12217 OMPC_atomic_default_mem_order, /*First=*/0,
12218 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
12219 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
12220 return nullptr;
12221 }
12222 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
12223 LParenLoc, EndLoc);
12224}
12225
12226OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
12227 SourceLocation KindKwLoc,
12228 SourceLocation StartLoc,
12229 SourceLocation LParenLoc,
12230 SourceLocation EndLoc) {
12231 if (Kind == OMPC_ORDER_unknown) {
12232 static_assert(OMPC_ORDER_unknown > 0,
12233 "OMPC_ORDER_unknown not greater than 0");
12234 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12235 << getListOfPossibleValues(OMPC_order, /*First=*/0,
12236 /*Last=*/OMPC_ORDER_unknown)
12237 << getOpenMPClauseName(OMPC_order);
12238 return nullptr;
12239 }
12240 return new (Context)
12241 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
12242}
12243
12244OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
12245 SourceLocation KindKwLoc,
12246 SourceLocation StartLoc,
12247 SourceLocation LParenLoc,
12248 SourceLocation EndLoc) {
12249 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
12250 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
12251 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
12252 OMPC_DEPEND_depobj};
12253 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12254 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12255 /*Last=*/OMPC_DEPEND_unknown, Except)
12256 << getOpenMPClauseName(OMPC_update);
12257 return nullptr;
12258 }
12259 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
12260 EndLoc);
12261}
12262
12263OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
12264 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
12265 SourceLocation StartLoc, SourceLocation LParenLoc,
12266 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
12267 SourceLocation EndLoc) {
12268 OMPClause *Res = nullptr;
12269 switch (Kind) {
12270 case OMPC_schedule:
12271 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
12272 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12273, __PRETTY_FUNCTION__))
12273 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12273, __PRETTY_FUNCTION__))
;
12274 Res = ActOnOpenMPScheduleClause(
12275 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
12276 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
12277 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
12278 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
12279 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
12280 break;
12281 case OMPC_if:
12282 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12282, __PRETTY_FUNCTION__))
;
12283 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
12284 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
12285 DelimLoc, EndLoc);
12286 break;
12287 case OMPC_dist_schedule:
12288 Res = ActOnOpenMPDistScheduleClause(
12289 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
12290 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
12291 break;
12292 case OMPC_defaultmap:
12293 enum { Modifier, DefaultmapKind };
12294 Res = ActOnOpenMPDefaultmapClause(
12295 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
12296 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
12297 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
12298 EndLoc);
12299 break;
12300 case OMPC_final:
12301 case OMPC_num_threads:
12302 case OMPC_safelen:
12303 case OMPC_simdlen:
12304 case OMPC_allocator:
12305 case OMPC_collapse:
12306 case OMPC_default:
12307 case OMPC_proc_bind:
12308 case OMPC_private:
12309 case OMPC_firstprivate:
12310 case OMPC_lastprivate:
12311 case OMPC_shared:
12312 case OMPC_reduction:
12313 case OMPC_task_reduction:
12314 case OMPC_in_reduction:
12315 case OMPC_linear:
12316 case OMPC_aligned:
12317 case OMPC_copyin:
12318 case OMPC_copyprivate:
12319 case OMPC_ordered:
12320 case OMPC_nowait:
12321 case OMPC_untied:
12322 case OMPC_mergeable:
12323 case OMPC_threadprivate:
12324 case OMPC_allocate:
12325 case OMPC_flush:
12326 case OMPC_depobj:
12327 case OMPC_read:
12328 case OMPC_write:
12329 case OMPC_update:
12330 case OMPC_capture:
12331 case OMPC_seq_cst:
12332 case OMPC_acq_rel:
12333 case OMPC_acquire:
12334 case OMPC_release:
12335 case OMPC_relaxed:
12336 case OMPC_depend:
12337 case OMPC_device:
12338 case OMPC_threads:
12339 case OMPC_simd:
12340 case OMPC_map:
12341 case OMPC_num_teams:
12342 case OMPC_thread_limit:
12343 case OMPC_priority:
12344 case OMPC_grainsize:
12345 case OMPC_nogroup:
12346 case OMPC_num_tasks:
12347 case OMPC_hint:
12348 case OMPC_unknown:
12349 case OMPC_uniform:
12350 case OMPC_to:
12351 case OMPC_from:
12352 case OMPC_use_device_ptr:
12353 case OMPC_is_device_ptr:
12354 case OMPC_unified_address:
12355 case OMPC_unified_shared_memory:
12356 case OMPC_reverse_offload:
12357 case OMPC_dynamic_allocators:
12358 case OMPC_atomic_default_mem_order:
12359 case OMPC_device_type:
12360 case OMPC_match:
12361 case OMPC_nontemporal:
12362 case OMPC_order:
12363 case OMPC_destroy:
12364 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12364)
;
12365 }
12366 return Res;
12367}
12368
12369static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
12370 OpenMPScheduleClauseModifier M2,
12371 SourceLocation M1Loc, SourceLocation M2Loc) {
12372 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
12373 SmallVector<unsigned, 2> Excluded;
12374 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
12375 Excluded.push_back(M2);
12376 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
12377 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
12378 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
12379 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
12380 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
12381 << getListOfPossibleValues(OMPC_schedule,
12382 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
12383 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
12384 Excluded)
12385 << getOpenMPClauseName(OMPC_schedule);
12386 return true;
12387 }
12388 return false;
12389}
12390
12391OMPClause *Sema::ActOnOpenMPScheduleClause(
12392 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
12393 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12394 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
12395 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
12396 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
12397 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
12398 return nullptr;
12399 // OpenMP, 2.7.1, Loop Construct, Restrictions
12400 // Either the monotonic modifier or the nonmonotonic modifier can be specified
12401 // but not both.
12402 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
12403 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
12404 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
12405 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
12406 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
12407 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
12408 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
12409 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
12410 return nullptr;
12411 }
12412 if (Kind == OMPC_SCHEDULE_unknown) {
12413 std::string Values;
12414 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
12415 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
12416 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
12417 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
12418 Exclude);
12419 } else {
12420 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
12421 /*Last=*/OMPC_SCHEDULE_unknown);
12422 }
12423 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12424 << Values << getOpenMPClauseName(OMPC_schedule);
12425 return nullptr;
12426 }
12427 // OpenMP, 2.7.1, Loop Construct, Restrictions
12428 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
12429 // schedule(guided).
12430 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
12431 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
12432 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
12433 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
12434 diag::err_omp_schedule_nonmonotonic_static);
12435 return nullptr;
12436 }
12437 Expr *ValExpr = ChunkSize;
12438 Stmt *HelperValStmt = nullptr;
12439 if (ChunkSize) {
12440 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12441 !ChunkSize->isInstantiationDependent() &&
12442 !ChunkSize->containsUnexpandedParameterPack()) {
12443 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
12444 ExprResult Val =
12445 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12446 if (Val.isInvalid())
12447 return nullptr;
12448
12449 ValExpr = Val.get();
12450
12451 // OpenMP [2.7.1, Restrictions]
12452 // chunk_size must be a loop invariant integer expression with a positive
12453 // value.
12454 llvm::APSInt Result;
12455 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12456 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12457 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12458 << "schedule" << 1 << ChunkSize->getSourceRange();
12459 return nullptr;
12460 }
12461 } else if (getOpenMPCaptureRegionForClause(
12462 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule,
12463 LangOpts.OpenMP) != OMPD_unknown &&
12464 !CurContext->isDependentContext()) {
12465 ValExpr = MakeFullExpr(ValExpr).get();
12466 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12467 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12468 HelperValStmt = buildPreInits(Context, Captures);
12469 }
12470 }
12471 }
12472
12473 return new (Context)
12474 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
12475 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
12476}
12477
12478OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
12479 SourceLocation StartLoc,
12480 SourceLocation EndLoc) {
12481 OMPClause *Res = nullptr;
12482 switch (Kind) {
12483 case OMPC_ordered:
12484 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
12485 break;
12486 case OMPC_nowait:
12487 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
12488 break;
12489 case OMPC_untied:
12490 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
12491 break;
12492 case OMPC_mergeable:
12493 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
12494 break;
12495 case OMPC_read:
12496 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
12497 break;
12498 case OMPC_write:
12499 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
12500 break;
12501 case OMPC_update:
12502 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
12503 break;
12504 case OMPC_capture:
12505 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
12506 break;
12507 case OMPC_seq_cst:
12508 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
12509 break;
12510 case OMPC_acq_rel:
12511 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
12512 break;
12513 case OMPC_acquire:
12514 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
12515 break;
12516 case OMPC_release:
12517 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
12518 break;
12519 case OMPC_relaxed:
12520 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
12521 break;
12522 case OMPC_threads:
12523 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
12524 break;
12525 case OMPC_simd:
12526 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
12527 break;
12528 case OMPC_nogroup:
12529 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
12530 break;
12531 case OMPC_unified_address:
12532 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
12533 break;
12534 case OMPC_unified_shared_memory:
12535 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
12536 break;
12537 case OMPC_reverse_offload:
12538 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
12539 break;
12540 case OMPC_dynamic_allocators:
12541 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
12542 break;
12543 case OMPC_destroy:
12544 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
12545 break;
12546 case OMPC_if:
12547 case OMPC_final:
12548 case OMPC_num_threads:
12549 case OMPC_safelen:
12550 case OMPC_simdlen:
12551 case OMPC_allocator:
12552 case OMPC_collapse:
12553 case OMPC_schedule:
12554 case OMPC_private:
12555 case OMPC_firstprivate:
12556 case OMPC_lastprivate:
12557 case OMPC_shared:
12558 case OMPC_reduction:
12559 case OMPC_task_reduction:
12560 case OMPC_in_reduction:
12561 case OMPC_linear:
12562 case OMPC_aligned:
12563 case OMPC_copyin:
12564 case OMPC_copyprivate:
12565 case OMPC_default:
12566 case OMPC_proc_bind:
12567 case OMPC_threadprivate:
12568 case OMPC_allocate:
12569 case OMPC_flush:
12570 case OMPC_depobj:
12571 case OMPC_depend:
12572 case OMPC_device:
12573 case OMPC_map:
12574 case OMPC_num_teams:
12575 case OMPC_thread_limit:
12576 case OMPC_priority:
12577 case OMPC_grainsize:
12578 case OMPC_num_tasks:
12579 case OMPC_hint:
12580 case OMPC_dist_schedule:
12581 case OMPC_defaultmap:
12582 case OMPC_unknown:
12583 case OMPC_uniform:
12584 case OMPC_to:
12585 case OMPC_from:
12586 case OMPC_use_device_ptr:
12587 case OMPC_is_device_ptr:
12588 case OMPC_atomic_default_mem_order:
12589 case OMPC_device_type:
12590 case OMPC_match:
12591 case OMPC_nontemporal:
12592 case OMPC_order:
12593 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12593)
;
12594 }
12595 return Res;
12596}
12597
12598OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
12599 SourceLocation EndLoc) {
12600 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
12601 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
12602}
12603
12604OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
12605 SourceLocation EndLoc) {
12606 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
12607}
12608
12609OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
12610 SourceLocation EndLoc) {
12611 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
12612}
12613
12614OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
12615 SourceLocation EndLoc) {
12616 return new (Context) OMPReadClause(StartLoc, EndLoc);
12617}
12618
12619OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
12620 SourceLocation EndLoc) {
12621 return new (Context) OMPWriteClause(StartLoc, EndLoc);
12622}
12623
12624OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
12625 SourceLocation EndLoc) {
12626 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
12627}
12628
12629OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
12630 SourceLocation EndLoc) {
12631 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
12632}
12633
12634OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
12635 SourceLocation EndLoc) {
12636 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
12637}
12638
12639OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
12640 SourceLocation EndLoc) {
12641 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
12642}
12643
12644OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
12645 SourceLocation EndLoc) {
12646 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
12647}
12648
12649OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
12650 SourceLocation EndLoc) {
12651 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
12652}
12653
12654OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
12655 SourceLocation EndLoc) {
12656 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
12657}
12658
12659OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
12660 SourceLocation EndLoc) {
12661 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
12662}
12663
12664OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
12665 SourceLocation EndLoc) {
12666 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
12667}
12668
12669OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
12670 SourceLocation EndLoc) {
12671 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
12672}
12673
12674OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
12675 SourceLocation EndLoc) {
12676 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
12677}
12678
12679OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
12680 SourceLocation EndLoc) {
12681 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
12682}
12683
12684OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
12685 SourceLocation EndLoc) {
12686 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
12687}
12688
12689OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
12690 SourceLocation EndLoc) {
12691 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
12692}
12693
12694OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
12695 SourceLocation EndLoc) {
12696 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
12697}
12698
12699OMPClause *Sema::ActOnOpenMPVarListClause(
12700 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
12701 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
12702 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
12703 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
12704 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
12705 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
12706 SourceLocation DepLinMapLastLoc) {
12707 SourceLocation StartLoc = Locs.StartLoc;
12708 SourceLocation LParenLoc = Locs.LParenLoc;
12709 SourceLocation EndLoc = Locs.EndLoc;
12710 OMPClause *Res = nullptr;
12711 switch (Kind) {
12712 case OMPC_private:
12713 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12714 break;
12715 case OMPC_firstprivate:
12716 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12717 break;
12718 case OMPC_lastprivate:
12719 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12720, __PRETTY_FUNCTION__))
12720 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12720, __PRETTY_FUNCTION__))
;
12721 Res = ActOnOpenMPLastprivateClause(
12722 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
12723 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
12724 break;
12725 case OMPC_shared:
12726 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
12727 break;
12728 case OMPC_reduction:
12729 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12730 EndLoc, ReductionOrMapperIdScopeSpec,
12731 ReductionOrMapperId);
12732 break;
12733 case OMPC_task_reduction:
12734 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12735 EndLoc, ReductionOrMapperIdScopeSpec,
12736 ReductionOrMapperId);
12737 break;
12738 case OMPC_in_reduction:
12739 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12740 EndLoc, ReductionOrMapperIdScopeSpec,
12741 ReductionOrMapperId);
12742 break;
12743 case OMPC_linear:
12744 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12745, __PRETTY_FUNCTION__))
12745 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12745, __PRETTY_FUNCTION__))
;
12746 Res = ActOnOpenMPLinearClause(
12747 VarList, TailExpr, StartLoc, LParenLoc,
12748 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc,
12749 ColonLoc, EndLoc);
12750 break;
12751 case OMPC_aligned:
12752 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
12753 ColonLoc, EndLoc);
12754 break;
12755 case OMPC_copyin:
12756 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
12757 break;
12758 case OMPC_copyprivate:
12759 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12760 break;
12761 case OMPC_flush:
12762 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
12763 break;
12764 case OMPC_depend:
12765 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12766, __PRETTY_FUNCTION__))
12766 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12766, __PRETTY_FUNCTION__))
;
12767 Res = ActOnOpenMPDependClause(
12768 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc,
12769 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
12770 break;
12771 case OMPC_map:
12772 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12773, __PRETTY_FUNCTION__))
12773 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12773, __PRETTY_FUNCTION__))
;
12774 Res = ActOnOpenMPMapClause(
12775 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
12776 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
12777 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs);
12778 break;
12779 case OMPC_to:
12780 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
12781 ReductionOrMapperId, Locs);
12782 break;
12783 case OMPC_from:
12784 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
12785 ReductionOrMapperId, Locs);
12786 break;
12787 case OMPC_use_device_ptr:
12788 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
12789 break;
12790 case OMPC_is_device_ptr:
12791 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
12792 break;
12793 case OMPC_allocate:
12794 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
12795 ColonLoc, EndLoc);
12796 break;
12797 case OMPC_nontemporal:
12798 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
12799 break;
12800 case OMPC_if:
12801 case OMPC_depobj:
12802 case OMPC_final:
12803 case OMPC_num_threads:
12804 case OMPC_safelen:
12805 case OMPC_simdlen:
12806 case OMPC_allocator:
12807 case OMPC_collapse:
12808 case OMPC_default:
12809 case OMPC_proc_bind:
12810 case OMPC_schedule:
12811 case OMPC_ordered:
12812 case OMPC_nowait:
12813 case OMPC_untied:
12814 case OMPC_mergeable:
12815 case OMPC_threadprivate:
12816 case OMPC_read:
12817 case OMPC_write:
12818 case OMPC_update:
12819 case OMPC_capture:
12820 case OMPC_seq_cst:
12821 case OMPC_acq_rel:
12822 case OMPC_acquire:
12823 case OMPC_release:
12824 case OMPC_relaxed:
12825 case OMPC_device:
12826 case OMPC_threads:
12827 case OMPC_simd:
12828 case OMPC_num_teams:
12829 case OMPC_thread_limit:
12830 case OMPC_priority:
12831 case OMPC_grainsize:
12832 case OMPC_nogroup:
12833 case OMPC_num_tasks:
12834 case OMPC_hint:
12835 case OMPC_dist_schedule:
12836 case OMPC_defaultmap:
12837 case OMPC_unknown:
12838 case OMPC_uniform:
12839 case OMPC_unified_address:
12840 case OMPC_unified_shared_memory:
12841 case OMPC_reverse_offload:
12842 case OMPC_dynamic_allocators:
12843 case OMPC_atomic_default_mem_order:
12844 case OMPC_device_type:
12845 case OMPC_match:
12846 case OMPC_order:
12847 case OMPC_destroy:
12848 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12848)
;
12849 }
12850 return Res;
12851}
12852
12853ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
12854 ExprObjectKind OK, SourceLocation Loc) {
12855 ExprResult Res = BuildDeclRefExpr(
12856 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
12857 if (!Res.isUsable())
12858 return ExprError();
12859 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
12860 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
12861 if (!Res.isUsable())
12862 return ExprError();
12863 }
12864 if (VK != VK_LValue && Res.get()->isGLValue()) {
12865 Res = DefaultLvalueConversion(Res.get());
12866 if (!Res.isUsable())
12867 return ExprError();
12868 }
12869 return Res;
12870}
12871
12872OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
12873 SourceLocation StartLoc,
12874 SourceLocation LParenLoc,
12875 SourceLocation EndLoc) {
12876 SmallVector<Expr *, 8> Vars;
12877 SmallVector<Expr *, 8> PrivateCopies;
12878 for (Expr *RefExpr : VarList) {
12879 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 12879, __PRETTY_FUNCTION__))
;
12880 SourceLocation ELoc;
12881 SourceRange ERange;
12882 Expr *SimpleRefExpr = RefExpr;
12883 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12884 if (Res.second) {
12885 // It will be analyzed later.
12886 Vars.push_back(RefExpr);
12887 PrivateCopies.push_back(nullptr);
12888 }
12889 ValueDecl *D = Res.first;
12890 if (!D)
12891 continue;
12892
12893 QualType Type = D->getType();
12894 auto *VD = dyn_cast<VarDecl>(D);
12895
12896 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12897 // A variable that appears in a private clause must not have an incomplete
12898 // type or a reference type.
12899 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
12900 continue;
12901 Type = Type.getNonReferenceType();
12902
12903 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12904 // A variable that is privatized must not have a const-qualified type
12905 // unless it is of class type with a mutable member. This restriction does
12906 // not apply to the firstprivate clause.
12907 //
12908 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
12909 // A variable that appears in a private clause must not have a
12910 // const-qualified type unless it is of class type with a mutable member.
12911 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
12912 continue;
12913
12914 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12915 // in a Construct]
12916 // Variables with the predetermined data-sharing attributes may not be
12917 // listed in data-sharing attributes clauses, except for the cases
12918 // listed below. For these exceptions only, listing a predetermined
12919 // variable in a data-sharing attribute clause is allowed and overrides
12920 // the variable's predetermined data-sharing attributes.
12921 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
12922 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
12923 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12924 << getOpenMPClauseName(OMPC_private);
12925 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
12926 continue;
12927 }
12928
12929 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12930 // Variably modified types are not supported for tasks.
12931 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
12932 isOpenMPTaskingDirective(CurrDir)) {
12933 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12934 << getOpenMPClauseName(OMPC_private) << Type
12935 << getOpenMPDirectiveName(CurrDir);
12936 bool IsDecl =
12937 !VD ||
12938 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12939 Diag(D->getLocation(),
12940 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12941 << D;
12942 continue;
12943 }
12944
12945 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12946 // A list item cannot appear in both a map clause and a data-sharing
12947 // attribute clause on the same construct
12948 //
12949 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12950 // A list item cannot appear in both a map clause and a data-sharing
12951 // attribute clause on the same construct unless the construct is a
12952 // combined construct.
12953 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
12954 CurrDir == OMPD_target) {
12955 OpenMPClauseKind ConflictKind;
12956 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
12957 VD, /*CurrentRegionOnly=*/true,
12958 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
12959 OpenMPClauseKind WhereFoundClauseKind) -> bool {
12960 ConflictKind = WhereFoundClauseKind;
12961 return true;
12962 })) {
12963 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12964 << getOpenMPClauseName(OMPC_private)
12965 << getOpenMPClauseName(ConflictKind)
12966 << getOpenMPDirectiveName(CurrDir);
12967 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
12968 continue;
12969 }
12970 }
12971
12972 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
12973 // A variable of class type (or array thereof) that appears in a private
12974 // clause requires an accessible, unambiguous default constructor for the
12975 // class type.
12976 // Generate helper private variable and initialize it with the default
12977 // value. The address of the original variable is replaced by the address of
12978 // the new private variable in CodeGen. This new variable is not added to
12979 // IdResolver, so the code in the OpenMP region uses original variable for
12980 // proper diagnostics.
12981 Type = Type.getUnqualifiedType();
12982 VarDecl *VDPrivate =
12983 buildVarDecl(*this, ELoc, Type, D->getName(),
12984 D->hasAttrs() ? &D->getAttrs() : nullptr,
12985 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12986 ActOnUninitializedDecl(VDPrivate);
12987 if (VDPrivate->isInvalidDecl())
12988 continue;
12989 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
12990 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12991
12992 DeclRefExpr *Ref = nullptr;
12993 if (!VD && !CurContext->isDependentContext())
12994 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
12995 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
12996 Vars.push_back((VD || CurContext->isDependentContext())
12997 ? RefExpr->IgnoreParens()
12998 : Ref);
12999 PrivateCopies.push_back(VDPrivateRefExpr);
13000 }
13001
13002 if (Vars.empty())
13003 return nullptr;
13004
13005 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13006 PrivateCopies);
13007}
13008
13009namespace {
13010class DiagsUninitializedSeveretyRAII {
13011private:
13012 DiagnosticsEngine &Diags;
13013 SourceLocation SavedLoc;
13014 bool IsIgnored = false;
13015
13016public:
13017 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
13018 bool IsIgnored)
13019 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
13020 if (!IsIgnored) {
13021 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
13022 /*Map*/ diag::Severity::Ignored, Loc);
13023 }
13024 }
13025 ~DiagsUninitializedSeveretyRAII() {
13026 if (!IsIgnored)
13027 Diags.popMappings(SavedLoc);
13028 }
13029};
13030}
13031
13032OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
13033 SourceLocation StartLoc,
13034 SourceLocation LParenLoc,
13035 SourceLocation EndLoc) {
13036 SmallVector<Expr *, 8> Vars;
13037 SmallVector<Expr *, 8> PrivateCopies;
13038 SmallVector<Expr *, 8> Inits;
13039 SmallVector<Decl *, 4> ExprCaptures;
13040 bool IsImplicitClause =
13041 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
13042 SourceLocation ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
13043
13044 for (Expr *RefExpr : VarList) {
13045 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 13045, __PRETTY_FUNCTION__))
;
13046 SourceLocation ELoc;
13047 SourceRange ERange;
13048 Expr *SimpleRefExpr = RefExpr;
13049 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13050 if (Res.second) {
13051 // It will be analyzed later.
13052 Vars.push_back(RefExpr);
13053 PrivateCopies.push_back(nullptr);
13054 Inits.push_back(nullptr);
13055 }
13056 ValueDecl *D = Res.first;
13057 if (!D)
13058 continue;
13059
13060 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
13061 QualType Type = D->getType();
13062 auto *VD = dyn_cast<VarDecl>(D);
13063
13064 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13065 // A variable that appears in a private clause must not have an incomplete
13066 // type or a reference type.
13067 if (RequireCompleteType(ELoc, Type,
13068 diag::err_omp_firstprivate_incomplete_type))
13069 continue;
13070 Type = Type.getNonReferenceType();
13071
13072 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
13073 // A variable of class type (or array thereof) that appears in a private
13074 // clause requires an accessible, unambiguous copy constructor for the
13075 // class type.
13076 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
13077
13078 // If an implicit firstprivate variable found it was checked already.
13079 DSAStackTy::DSAVarData TopDVar;
13080 if (!IsImplicitClause) {
13081 DSAStackTy::DSAVarData DVar =
13082 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13083 TopDVar = DVar;
13084 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13085 bool IsConstant = ElemType.isConstant(Context);
13086 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
13087 // A list item that specifies a given variable may not appear in more
13088 // than one clause on the same directive, except that a variable may be
13089 // specified in both firstprivate and lastprivate clauses.
13090 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13091 // A list item may appear in a firstprivate or lastprivate clause but not
13092 // both.
13093 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
13094 (isOpenMPDistributeDirective(CurrDir) ||
13095 DVar.CKind != OMPC_lastprivate) &&
13096 DVar.RefExpr) {
13097 Diag(ELoc, diag::err_omp_wrong_dsa)
13098 << getOpenMPClauseName(DVar.CKind)
13099 << getOpenMPClauseName(OMPC_firstprivate);
13100 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13101 continue;
13102 }
13103
13104 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13105 // in a Construct]
13106 // Variables with the predetermined data-sharing attributes may not be
13107 // listed in data-sharing attributes clauses, except for the cases
13108 // listed below. For these exceptions only, listing a predetermined
13109 // variable in a data-sharing attribute clause is allowed and overrides
13110 // the variable's predetermined data-sharing attributes.
13111 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13112 // in a Construct, C/C++, p.2]
13113 // Variables with const-qualified type having no mutable member may be
13114 // listed in a firstprivate clause, even if they are static data members.
13115 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
13116 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
13117 Diag(ELoc, diag::err_omp_wrong_dsa)
13118 << getOpenMPClauseName(DVar.CKind)
13119 << getOpenMPClauseName(OMPC_firstprivate);
13120 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13121 continue;
13122 }
13123
13124 // OpenMP [2.9.3.4, Restrictions, p.2]
13125 // A list item that is private within a parallel region must not appear
13126 // in a firstprivate clause on a worksharing construct if any of the
13127 // worksharing regions arising from the worksharing construct ever bind
13128 // to any of the parallel regions arising from the parallel construct.
13129 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13130 // A list item that is private within a teams region must not appear in a
13131 // firstprivate clause on a distribute construct if any of the distribute
13132 // regions arising from the distribute construct ever bind to any of the
13133 // teams regions arising from the teams construct.
13134 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13135 // A list item that appears in a reduction clause of a teams construct
13136 // must not appear in a firstprivate clause on a distribute construct if
13137 // any of the distribute regions arising from the distribute construct
13138 // ever bind to any of the teams regions arising from the teams construct.
13139 if ((isOpenMPWorksharingDirective(CurrDir) ||
13140 isOpenMPDistributeDirective(CurrDir)) &&
13141 !isOpenMPParallelDirective(CurrDir) &&
13142 !isOpenMPTeamsDirective(CurrDir)) {
13143 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
13144 if (DVar.CKind != OMPC_shared &&
13145 (isOpenMPParallelDirective(DVar.DKind) ||
13146 isOpenMPTeamsDirective(DVar.DKind) ||
13147 DVar.DKind == OMPD_unknown)) {
13148 Diag(ELoc, diag::err_omp_required_access)
13149 << getOpenMPClauseName(OMPC_firstprivate)
13150 << getOpenMPClauseName(OMPC_shared);
13151 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13152 continue;
13153 }
13154 }
13155 // OpenMP [2.9.3.4, Restrictions, p.3]
13156 // A list item that appears in a reduction clause of a parallel construct
13157 // must not appear in a firstprivate clause on a worksharing or task
13158 // construct if any of the worksharing or task regions arising from the
13159 // worksharing or task construct ever bind to any of the parallel regions
13160 // arising from the parallel construct.
13161 // OpenMP [2.9.3.4, Restrictions, p.4]
13162 // A list item that appears in a reduction clause in worksharing
13163 // construct must not appear in a firstprivate clause in a task construct
13164 // encountered during execution of any of the worksharing regions arising
13165 // from the worksharing construct.
13166 if (isOpenMPTaskingDirective(CurrDir)) {
13167 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
13168 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
13169 [](OpenMPDirectiveKind K) {
13170 return isOpenMPParallelDirective(K) ||
13171 isOpenMPWorksharingDirective(K) ||
13172 isOpenMPTeamsDirective(K);
13173 },
13174 /*FromParent=*/true);
13175 if (DVar.CKind == OMPC_reduction &&
13176 (isOpenMPParallelDirective(DVar.DKind) ||
13177 isOpenMPWorksharingDirective(DVar.DKind) ||
13178 isOpenMPTeamsDirective(DVar.DKind))) {
13179 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
13180 << getOpenMPDirectiveName(DVar.DKind);
13181 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13182 continue;
13183 }
13184 }
13185
13186 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13187 // A list item cannot appear in both a map clause and a data-sharing
13188 // attribute clause on the same construct
13189 //
13190 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13191 // A list item cannot appear in both a map clause and a data-sharing
13192 // attribute clause on the same construct unless the construct is a
13193 // combined construct.
13194 if ((LangOpts.OpenMP <= 45 &&
13195 isOpenMPTargetExecutionDirective(CurrDir)) ||
13196 CurrDir == OMPD_target) {
13197 OpenMPClauseKind ConflictKind;
13198 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
13199 VD, /*CurrentRegionOnly=*/true,
13200 [&ConflictKind](
13201 OMPClauseMappableExprCommon::MappableExprComponentListRef,
13202 OpenMPClauseKind WhereFoundClauseKind) {
13203 ConflictKind = WhereFoundClauseKind;
13204 return true;
13205 })) {
13206 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13207 << getOpenMPClauseName(OMPC_firstprivate)
13208 << getOpenMPClauseName(ConflictKind)
13209 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
13210 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13211 continue;
13212 }
13213 }
13214 }
13215
13216 // Variably modified types are not supported for tasks.
13217 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13218 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
13219 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13220 << getOpenMPClauseName(OMPC_firstprivate) << Type
13221 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
13222 bool IsDecl =
13223 !VD ||
13224 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13225 Diag(D->getLocation(),
13226 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13227 << D;
13228 continue;
13229 }
13230
13231 Type = Type.getUnqualifiedType();
13232 VarDecl *VDPrivate =
13233 buildVarDecl(*this, ELoc, Type, D->getName(),
13234 D->hasAttrs() ? &D->getAttrs() : nullptr,
13235 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13236 // Generate helper private variable and initialize it with the value of the
13237 // original variable. The address of the original variable is replaced by
13238 // the address of the new private variable in the CodeGen. This new variable
13239 // is not added to IdResolver, so the code in the OpenMP region uses
13240 // original variable for proper diagnostics and variable capturing.
13241 Expr *VDInitRefExpr = nullptr;
13242 // For arrays generate initializer for single element and replace it by the
13243 // original array element in CodeGen.
13244 if (Type->isArrayType()) {
13245 VarDecl *VDInit =
13246 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
13247 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
13248 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
13249 ElemType = ElemType.getUnqualifiedType();
13250 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
13251 ".firstprivate.temp");
13252 InitializedEntity Entity =
13253 InitializedEntity::InitializeVariable(VDInitTemp);
13254 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
13255
13256 InitializationSequence InitSeq(*this, Entity, Kind, Init);
13257 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
13258 if (Result.isInvalid())
13259 VDPrivate->setInvalidDecl();
13260 else
13261 VDPrivate->setInit(Result.getAs<Expr>());
13262 // Remove temp variable declaration.
13263 Context.Deallocate(VDInitTemp);
13264 } else {
13265 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
13266 ".firstprivate.temp");
13267 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
13268 RefExpr->getExprLoc());
13269 AddInitializerToDecl(VDPrivate,
13270 DefaultLvalueConversion(VDInitRefExpr).get(),
13271 /*DirectInit=*/false);
13272 }
13273 if (VDPrivate->isInvalidDecl()) {
13274 if (IsImplicitClause) {
13275 Diag(RefExpr->getExprLoc(),
13276 diag::note_omp_task_predetermined_firstprivate_here);
13277 }
13278 continue;
13279 }
13280 CurContext->addDecl(VDPrivate);
13281 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13282 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
13283 RefExpr->getExprLoc());
13284 DeclRefExpr *Ref = nullptr;
13285 if (!VD && !CurContext->isDependentContext()) {
13286 if (TopDVar.CKind == OMPC_lastprivate) {
13287 Ref = TopDVar.PrivateCopy;
13288 } else {
13289 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13290 if (!isOpenMPCapturedDecl(D))
13291 ExprCaptures.push_back(Ref->getDecl());
13292 }
13293 }
13294 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13295 Vars.push_back((VD || CurContext->isDependentContext())
13296 ? RefExpr->IgnoreParens()
13297 : Ref);
13298 PrivateCopies.push_back(VDPrivateRefExpr);
13299 Inits.push_back(VDInitRefExpr);
13300 }
13301
13302 if (Vars.empty())
13303 return nullptr;
13304
13305 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13306 Vars, PrivateCopies, Inits,
13307 buildPreInits(Context, ExprCaptures));
13308}
13309
13310OMPClause *Sema::ActOnOpenMPLastprivateClause(
13311 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
13312 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
13313 SourceLocation LParenLoc, SourceLocation EndLoc) {
13314 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
13315 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 13315, __PRETTY_FUNCTION__))
;
13316 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
13317 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
13318 /*Last=*/OMPC_LASTPRIVATE_unknown)
13319 << getOpenMPClauseName(OMPC_lastprivate);
13320 return nullptr;
13321 }
13322
13323 SmallVector<Expr *, 8> Vars;
13324 SmallVector<Expr *, 8> SrcExprs;
13325 SmallVector<Expr *, 8> DstExprs;
13326 SmallVector<Expr *, 8> AssignmentOps;
13327 SmallVector<Decl *, 4> ExprCaptures;
13328 SmallVector<Expr *, 4> ExprPostUpdates;
13329 for (Expr *RefExpr : VarList) {
13330 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 13330, __PRETTY_FUNCTION__))
;
13331 SourceLocation ELoc;
13332 SourceRange ERange;
13333 Expr *SimpleRefExpr = RefExpr;
13334 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13335 if (Res.second) {
13336 // It will be analyzed later.
13337 Vars.push_back(RefExpr);
13338 SrcExprs.push_back(nullptr);
13339 DstExprs.push_back(nullptr);
13340 AssignmentOps.push_back(nullptr);
13341 }
13342 ValueDecl *D = Res.first;
13343 if (!D)
13344 continue;
13345
13346 QualType Type = D->getType();
13347 auto *VD = dyn_cast<VarDecl>(D);
13348
13349 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
13350 // A variable that appears in a lastprivate clause must not have an
13351 // incomplete type or a reference type.
13352 if (RequireCompleteType(ELoc, Type,
13353 diag::err_omp_lastprivate_incomplete_type))
13354 continue;
13355 Type = Type.getNonReferenceType();
13356
13357 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13358 // A variable that is privatized must not have a const-qualified type
13359 // unless it is of class type with a mutable member. This restriction does
13360 // not apply to the firstprivate clause.
13361 //
13362 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
13363 // A variable that appears in a lastprivate clause must not have a
13364 // const-qualified type unless it is of class type with a mutable member.
13365 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
13366 continue;
13367
13368 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
13369 // A list item that appears in a lastprivate clause with the conditional
13370 // modifier must be a scalar variable.
13371 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
13372 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
13373 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13374 VarDecl::DeclarationOnly;
13375 Diag(D->getLocation(),
13376 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13377 << D;
13378 continue;
13379 }
13380
13381 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
13382 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
13383 // in a Construct]
13384 // Variables with the predetermined data-sharing attributes may not be
13385 // listed in data-sharing attributes clauses, except for the cases
13386 // listed below.
13387 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13388 // A list item may appear in a firstprivate or lastprivate clause but not
13389 // both.
13390 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13391 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
13392 (isOpenMPDistributeDirective(CurrDir) ||
13393 DVar.CKind != OMPC_firstprivate) &&
13394 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
13395 Diag(ELoc, diag::err_omp_wrong_dsa)
13396 << getOpenMPClauseName(DVar.CKind)
13397 << getOpenMPClauseName(OMPC_lastprivate);
13398 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13399 continue;
13400 }
13401
13402 // OpenMP [2.14.3.5, Restrictions, p.2]
13403 // A list item that is private within a parallel region, or that appears in
13404 // the reduction clause of a parallel construct, must not appear in a
13405 // lastprivate clause on a worksharing construct if any of the corresponding
13406 // worksharing regions ever binds to any of the corresponding parallel
13407 // regions.
13408 DSAStackTy::DSAVarData TopDVar = DVar;
13409 if (isOpenMPWorksharingDirective(CurrDir) &&
13410 !isOpenMPParallelDirective(CurrDir) &&
13411 !isOpenMPTeamsDirective(CurrDir)) {
13412 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
13413 if (DVar.CKind != OMPC_shared) {
13414 Diag(ELoc, diag::err_omp_required_access)
13415 << getOpenMPClauseName(OMPC_lastprivate)
13416 << getOpenMPClauseName(OMPC_shared);
13417 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13418 continue;
13419 }
13420 }
13421
13422 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
13423 // A variable of class type (or array thereof) that appears in a
13424 // lastprivate clause requires an accessible, unambiguous default
13425 // constructor for the class type, unless the list item is also specified
13426 // in a firstprivate clause.
13427 // A variable of class type (or array thereof) that appears in a
13428 // lastprivate clause requires an accessible, unambiguous copy assignment
13429 // operator for the class type.
13430 Type = Context.getBaseElementType(Type).getNonReferenceType();
13431 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
13432 Type.getUnqualifiedType(), ".lastprivate.src",
13433 D->hasAttrs() ? &D->getAttrs() : nullptr);
13434 DeclRefExpr *PseudoSrcExpr =
13435 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
13436 VarDecl *DstVD =
13437 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
13438 D->hasAttrs() ? &D->getAttrs() : nullptr);
13439 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
13440 // For arrays generate assignment operation for single element and replace
13441 // it by the original array element in CodeGen.
13442 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
13443 PseudoDstExpr, PseudoSrcExpr);
13444 if (AssignmentOp.isInvalid())
13445 continue;
13446 AssignmentOp =
13447 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
13448 if (AssignmentOp.isInvalid())
13449 continue;
13450
13451 DeclRefExpr *Ref = nullptr;
13452 if (!VD && !CurContext->isDependentContext()) {
13453 if (TopDVar.CKind == OMPC_firstprivate) {
13454 Ref = TopDVar.PrivateCopy;
13455 } else {
13456 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13457 if (!isOpenMPCapturedDecl(D))
13458 ExprCaptures.push_back(Ref->getDecl());
13459 }
13460 if (TopDVar.CKind == OMPC_firstprivate ||
13461 (!isOpenMPCapturedDecl(D) &&
13462 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
13463 ExprResult RefRes = DefaultLvalueConversion(Ref);
13464 if (!RefRes.isUsable())
13465 continue;
13466 ExprResult PostUpdateRes =
13467 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
13468 RefRes.get());
13469 if (!PostUpdateRes.isUsable())
13470 continue;
13471 ExprPostUpdates.push_back(
13472 IgnoredValueConversions(PostUpdateRes.get()).get());
13473 }
13474 }
13475 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
13476 Vars.push_back((VD || CurContext->isDependentContext())
13477 ? RefExpr->IgnoreParens()
13478 : Ref);
13479 SrcExprs.push_back(PseudoSrcExpr);
13480 DstExprs.push_back(PseudoDstExpr);
13481 AssignmentOps.push_back(AssignmentOp.get());
13482 }
13483
13484 if (Vars.empty())
13485 return nullptr;
13486
13487 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13488 Vars, SrcExprs, DstExprs, AssignmentOps,
13489 LPKind, LPKindLoc, ColonLoc,
13490 buildPreInits(Context, ExprCaptures),
13491 buildPostUpdate(*this, ExprPostUpdates));
13492}
13493
13494OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
13495 SourceLocation StartLoc,
13496 SourceLocation LParenLoc,
13497 SourceLocation EndLoc) {
13498 SmallVector<Expr *, 8> Vars;
13499 for (Expr *RefExpr : VarList) {
13500 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 13500, __PRETTY_FUNCTION__))
;
13501 SourceLocation ELoc;
13502 SourceRange ERange;
13503 Expr *SimpleRefExpr = RefExpr;
13504 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13505 if (Res.second) {
13506 // It will be analyzed later.
13507 Vars.push_back(RefExpr);
13508 }
13509 ValueDecl *D = Res.first;
13510 if (!D)
13511 continue;
13512
13513 auto *VD = dyn_cast<VarDecl>(D);
13514 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13515 // in a Construct]
13516 // Variables with the predetermined data-sharing attributes may not be
13517 // listed in data-sharing attributes clauses, except for the cases
13518 // listed below. For these exceptions only, listing a predetermined
13519 // variable in a data-sharing attribute clause is allowed and overrides
13520 // the variable's predetermined data-sharing attributes.
13521 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
13522 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
13523 DVar.RefExpr) {
13524 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13525 << getOpenMPClauseName(OMPC_shared);
13526 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13527 continue;
13528 }
13529
13530 DeclRefExpr *Ref = nullptr;
13531 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
13532 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13533 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
13534 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
13535 ? RefExpr->IgnoreParens()
13536 : Ref);
13537 }
13538
13539 if (Vars.empty())
13540 return nullptr;
13541
13542 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
13543}
13544
13545namespace {
13546class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
13547 DSAStackTy *Stack;
13548
13549public:
13550 bool VisitDeclRefExpr(DeclRefExpr *E) {
13551 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
13552 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
13553 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
13554 return false;
13555 if (DVar.CKind != OMPC_unknown)
13556 return true;
13557 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
13558 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
13559 /*FromParent=*/true);
13560 return DVarPrivate.CKind != OMPC_unknown;
13561 }
13562 return false;
13563 }
13564 bool VisitStmt(Stmt *S) {
13565 for (Stmt *Child : S->children()) {
13566 if (Child && Visit(Child))
13567 return true;
13568 }
13569 return false;
13570 }
13571 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
13572};
13573} // namespace
13574
13575namespace {
13576// Transform MemberExpression for specified FieldDecl of current class to
13577// DeclRefExpr to specified OMPCapturedExprDecl.
13578class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
13579 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
13580 ValueDecl *Field = nullptr;
13581 DeclRefExpr *CapturedExpr = nullptr;
13582
13583public:
13584 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
13585 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
13586
13587 ExprResult TransformMemberExpr(MemberExpr *E) {
13588 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
13589 E->getMemberDecl() == Field) {
13590 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
13591 return CapturedExpr;
13592 }
13593 return BaseTransform::TransformMemberExpr(E);
13594 }
13595 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
13596};
13597} // namespace
13598
13599template <typename T, typename U>
13600static T filterLookupForUDReductionAndMapper(
13601 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
13602 for (U &Set : Lookups) {
13603 for (auto *D : Set) {
13604 if (T Res = Gen(cast<ValueDecl>(D)))
13605 return Res;
13606 }
13607 }
13608 return T();
13609}
13610
13611static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
13612 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 13612, __PRETTY_FUNCTION__))
;
13613
13614 for (auto RD : D->redecls()) {
13615 // Don't bother with extra checks if we already know this one isn't visible.
13616 if (RD == D)
13617 continue;
13618
13619 auto ND = cast<NamedDecl>(RD);
13620 if (LookupResult::isVisible(SemaRef, ND))
13621 return ND;
13622 }
13623
13624 return nullptr;
13625}
13626
13627static void
13628argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
13629 SourceLocation Loc, QualType Ty,
13630 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
13631 // Find all of the associated namespaces and classes based on the
13632 // arguments we have.
13633 Sema::AssociatedNamespaceSet AssociatedNamespaces;
13634 Sema::AssociatedClassSet AssociatedClasses;
13635 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
13636 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
13637 AssociatedClasses);
13638
13639 // C++ [basic.lookup.argdep]p3:
13640 // Let X be the lookup set produced by unqualified lookup (3.4.1)
13641 // and let Y be the lookup set produced by argument dependent
13642 // lookup (defined as follows). If X contains [...] then Y is
13643 // empty. Otherwise Y is the set of declarations found in the
13644 // namespaces associated with the argument types as described
13645 // below. The set of declarations found by the lookup of the name
13646 // is the union of X and Y.
13647 //
13648 // Here, we compute Y and add its members to the overloaded
13649 // candidate set.
13650 for (auto *NS : AssociatedNamespaces) {
13651 // When considering an associated namespace, the lookup is the
13652 // same as the lookup performed when the associated namespace is
13653 // used as a qualifier (3.4.3.2) except that:
13654 //
13655 // -- Any using-directives in the associated namespace are
13656 // ignored.
13657 //
13658 // -- Any namespace-scope friend functions declared in
13659 // associated classes are visible within their respective
13660 // namespaces even if they are not visible during an ordinary
13661 // lookup (11.4).
13662 DeclContext::lookup_result R = NS->lookup(Id.getName());
13663 for (auto *D : R) {
13664 auto *Underlying = D;
13665 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
13666 Underlying = USD->getTargetDecl();
13667
13668 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
13669 !isa<OMPDeclareMapperDecl>(Underlying))
13670 continue;
13671
13672 if (!SemaRef.isVisible(D)) {
13673 D = findAcceptableDecl(SemaRef, D);
13674 if (!D)
13675 continue;
13676 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
13677 Underlying = USD->getTargetDecl();
13678 }
13679 Lookups.emplace_back();
13680 Lookups.back().addDecl(Underlying);
13681 }
13682 }
13683}
13684
13685static ExprResult
13686buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
13687 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
13688 const DeclarationNameInfo &ReductionId, QualType Ty,
13689 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
13690 if (ReductionIdScopeSpec.isInvalid())
13691 return ExprError();
13692 SmallVector<UnresolvedSet<8>, 4> Lookups;
13693 if (S) {
13694 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
13695 Lookup.suppressDiagnostics();
13696 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
13697 NamedDecl *D = Lookup.getRepresentativeDecl();
13698 do {
13699 S = S->getParent();
13700 } while (S && !S->isDeclScope(D));
13701 if (S)
13702 S = S->getParent();
13703 Lookups.emplace_back();
13704 Lookups.back().append(Lookup.begin(), Lookup.end());
13705 Lookup.clear();
13706 }
13707 } else if (auto *ULE =
13708 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
13709 Lookups.push_back(UnresolvedSet<8>());
13710 Decl *PrevD = nullptr;
13711 for (NamedDecl *D : ULE->decls()) {
13712 if (D == PrevD)
13713 Lookups.push_back(UnresolvedSet<8>());
13714 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
13715 Lookups.back().addDecl(DRD);
13716 PrevD = D;
13717 }
13718 }
13719 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
13720 Ty->isInstantiationDependentType() ||
13721 Ty->containsUnexpandedParameterPack() ||
13722 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
13723 return !D->isInvalidDecl() &&
13724 (D->getType()->isDependentType() ||
13725 D->getType()->isInstantiationDependentType() ||
13726 D->getType()->containsUnexpandedParameterPack());
13727 })) {
13728 UnresolvedSet<8> ResSet;
13729 for (const UnresolvedSet<8> &Set : Lookups) {
13730 if (Set.empty())
13731 continue;
13732 ResSet.append(Set.begin(), Set.end());
13733 // The last item marks the end of all declarations at the specified scope.
13734 ResSet.addDecl(Set[Set.size() - 1]);
13735 }
13736 return UnresolvedLookupExpr::Create(
13737 SemaRef.Context, /*NamingClass=*/nullptr,
13738 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
13739 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
13740 }
13741 // Lookup inside the classes.
13742 // C++ [over.match.oper]p3:
13743 // For a unary operator @ with an operand of a type whose
13744 // cv-unqualified version is T1, and for a binary operator @ with
13745 // a left operand of a type whose cv-unqualified version is T1 and
13746 // a right operand of a type whose cv-unqualified version is T2,
13747 // three sets of candidate functions, designated member
13748 // candidates, non-member candidates and built-in candidates, are
13749 // constructed as follows:
13750 // -- If T1 is a complete class type or a class currently being
13751 // defined, the set of member candidates is the result of the
13752 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
13753 // the set of member candidates is empty.
13754 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
13755 Lookup.suppressDiagnostics();
13756 if (const auto *TyRec = Ty->getAs<RecordType>()) {
13757 // Complete the type if it can be completed.
13758 // If the type is neither complete nor being defined, bail out now.
13759 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
13760 TyRec->getDecl()->getDefinition()) {
13761 Lookup.clear();
13762 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
13763 if (Lookup.empty()) {
13764 Lookups.emplace_back();
13765 Lookups.back().append(Lookup.begin(), Lookup.end());
13766 }
13767 }
13768 }
13769 // Perform ADL.
13770 if (SemaRef.getLangOpts().CPlusPlus)
13771 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
13772 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13773 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
13774 if (!D->isInvalidDecl() &&
13775 SemaRef.Context.hasSameType(D->getType(), Ty))
13776 return D;
13777 return nullptr;
13778 }))
13779 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
13780 VK_LValue, Loc);
13781 if (SemaRef.getLangOpts().CPlusPlus) {
13782 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13783 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
13784 if (!D->isInvalidDecl() &&
13785 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
13786 !Ty.isMoreQualifiedThan(D->getType()))
13787 return D;
13788 return nullptr;
13789 })) {
13790 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
13791 /*DetectVirtual=*/false);
13792 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
13793 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
13794 VD->getType().getUnqualifiedType()))) {
13795 if (SemaRef.CheckBaseClassAccess(
13796 Loc, VD->getType(), Ty, Paths.front(),
13797 /*DiagID=*/0) != Sema::AR_inaccessible) {
13798 SemaRef.BuildBasePathArray(Paths, BasePath);
13799 return SemaRef.BuildDeclRefExpr(
13800 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
13801 }
13802 }
13803 }
13804 }
13805 }
13806 if (ReductionIdScopeSpec.isSet()) {
13807 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
13808 << Ty << Range;
13809 return ExprError();
13810 }
13811 return ExprEmpty();
13812}
13813
13814namespace {
13815/// Data for the reduction-based clauses.
13816struct ReductionData {
13817 /// List of original reduction items.
13818 SmallVector<Expr *, 8> Vars;
13819 /// List of private copies of the reduction items.
13820 SmallVector<Expr *, 8> Privates;
13821 /// LHS expressions for the reduction_op expressions.
13822 SmallVector<Expr *, 8> LHSs;
13823 /// RHS expressions for the reduction_op expressions.
13824 SmallVector<Expr *, 8> RHSs;
13825 /// Reduction operation expression.
13826 SmallVector<Expr *, 8> ReductionOps;
13827 /// Taskgroup descriptors for the corresponding reduction items in
13828 /// in_reduction clauses.
13829 SmallVector<Expr *, 8> TaskgroupDescriptors;
13830 /// List of captures for clause.
13831 SmallVector<Decl *, 4> ExprCaptures;
13832 /// List of postupdate expressions.
13833 SmallVector<Expr *, 4> ExprPostUpdates;
13834 ReductionData() = delete;
13835 /// Reserves required memory for the reduction data.
13836 ReductionData(unsigned Size) {
13837 Vars.reserve(Size);
13838 Privates.reserve(Size);
13839 LHSs.reserve(Size);
13840 RHSs.reserve(Size);
13841 ReductionOps.reserve(Size);
13842 TaskgroupDescriptors.reserve(Size);
13843 ExprCaptures.reserve(Size);
13844 ExprPostUpdates.reserve(Size);
13845 }
13846 /// Stores reduction item and reduction operation only (required for dependent
13847 /// reduction item).
13848 void push(Expr *Item, Expr *ReductionOp) {
13849 Vars.emplace_back(Item);
13850 Privates.emplace_back(nullptr);
13851 LHSs.emplace_back(nullptr);
13852 RHSs.emplace_back(nullptr);
13853 ReductionOps.emplace_back(ReductionOp);
13854 TaskgroupDescriptors.emplace_back(nullptr);
13855 }
13856 /// Stores reduction data.
13857 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
13858 Expr *TaskgroupDescriptor) {
13859 Vars.emplace_back(Item);
13860 Privates.emplace_back(Private);
13861 LHSs.emplace_back(LHS);
13862 RHSs.emplace_back(RHS);
13863 ReductionOps.emplace_back(ReductionOp);
13864 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
13865 }
13866};
13867} // namespace
13868
13869static bool checkOMPArraySectionConstantForReduction(
13870 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
13871 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
13872 const Expr *Length = OASE->getLength();
13873 if (Length == nullptr) {
13874 // For array sections of the form [1:] or [:], we would need to analyze
13875 // the lower bound...
13876 if (OASE->getColonLoc().isValid())
13877 return false;
13878
13879 // This is an array subscript which has implicit length 1!
13880 SingleElement = true;
13881 ArraySizes.push_back(llvm::APSInt::get(1));
13882 } else {
13883 Expr::EvalResult Result;
13884 if (!Length->EvaluateAsInt(Result, Context))
13885 return false;
13886
13887 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13888 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
13889 ArraySizes.push_back(ConstantLengthValue);
13890 }
13891
13892 // Get the base of this array section and walk up from there.
13893 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
13894
13895 // We require length = 1 for all array sections except the right-most to
13896 // guarantee that the memory region is contiguous and has no holes in it.
13897 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
13898 Length = TempOASE->getLength();
13899 if (Length == nullptr) {
13900 // For array sections of the form [1:] or [:], we would need to analyze
13901 // the lower bound...
13902 if (OASE->getColonLoc().isValid())
13903 return false;
13904
13905 // This is an array subscript which has implicit length 1!
13906 ArraySizes.push_back(llvm::APSInt::get(1));
13907 } else {
13908 Expr::EvalResult Result;
13909 if (!Length->EvaluateAsInt(Result, Context))
13910 return false;
13911
13912 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13913 if (ConstantLengthValue.getSExtValue() != 1)
13914 return false;
13915
13916 ArraySizes.push_back(ConstantLengthValue);
13917 }
13918 Base = TempOASE->getBase()->IgnoreParenImpCasts();
13919 }
13920
13921 // If we have a single element, we don't need to add the implicit lengths.
13922 if (!SingleElement) {
13923 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
13924 // Has implicit length 1!
13925 ArraySizes.push_back(llvm::APSInt::get(1));
13926 Base = TempASE->getBase()->IgnoreParenImpCasts();
13927 }
13928 }
13929
13930 // This array section can be privatized as a single value or as a constant
13931 // sized array.
13932 return true;
13933}
13934
13935static bool actOnOMPReductionKindClause(
13936 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
13937 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13938 SourceLocation ColonLoc, SourceLocation EndLoc,
13939 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13940 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
13941 DeclarationName DN = ReductionId.getName();
13942 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
13943 BinaryOperatorKind BOK = BO_Comma;
13944
13945 ASTContext &Context = S.Context;
13946 // OpenMP [2.14.3.6, reduction clause]
13947 // C
13948 // reduction-identifier is either an identifier or one of the following
13949 // operators: +, -, *, &, |, ^, && and ||
13950 // C++
13951 // reduction-identifier is either an id-expression or one of the following
13952 // operators: +, -, *, &, |, ^, && and ||
13953 switch (OOK) {
13954 case OO_Plus:
13955 case OO_Minus:
13956 BOK = BO_Add;
13957 break;
13958 case OO_Star:
13959 BOK = BO_Mul;
13960 break;
13961 case OO_Amp:
13962 BOK = BO_And;
13963 break;
13964 case OO_Pipe:
13965 BOK = BO_Or;
13966 break;
13967 case OO_Caret:
13968 BOK = BO_Xor;
13969 break;
13970 case OO_AmpAmp:
13971 BOK = BO_LAnd;
13972 break;
13973 case OO_PipePipe:
13974 BOK = BO_LOr;
13975 break;
13976 case OO_New:
13977 case OO_Delete:
13978 case OO_Array_New:
13979 case OO_Array_Delete:
13980 case OO_Slash:
13981 case OO_Percent:
13982 case OO_Tilde:
13983 case OO_Exclaim:
13984 case OO_Equal:
13985 case OO_Less:
13986 case OO_Greater:
13987 case OO_LessEqual:
13988 case OO_GreaterEqual:
13989 case OO_PlusEqual:
13990 case OO_MinusEqual:
13991 case OO_StarEqual:
13992 case OO_SlashEqual:
13993 case OO_PercentEqual:
13994 case OO_CaretEqual:
13995 case OO_AmpEqual:
13996 case OO_PipeEqual:
13997 case OO_LessLess:
13998 case OO_GreaterGreater:
13999 case OO_LessLessEqual:
14000 case OO_GreaterGreaterEqual:
14001 case OO_EqualEqual:
14002 case OO_ExclaimEqual:
14003 case OO_Spaceship:
14004 case OO_PlusPlus:
14005 case OO_MinusMinus:
14006 case OO_Comma:
14007 case OO_ArrowStar:
14008 case OO_Arrow:
14009 case OO_Call:
14010 case OO_Subscript:
14011 case OO_Conditional:
14012 case OO_Coawait:
14013 case NUM_OVERLOADED_OPERATORS:
14014 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14014)
;
14015 case OO_None:
14016 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
14017 if (II->isStr("max"))
14018 BOK = BO_GT;
14019 else if (II->isStr("min"))
14020 BOK = BO_LT;
14021 }
14022 break;
14023 }
14024 SourceRange ReductionIdRange;
14025 if (ReductionIdScopeSpec.isValid())
14026 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
14027 else
14028 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
14029 ReductionIdRange.setEnd(ReductionId.getEndLoc());
14030
14031 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
14032 bool FirstIter = true;
14033 for (Expr *RefExpr : VarList) {
14034 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14034, __PRETTY_FUNCTION__))
;
14035 // OpenMP [2.1, C/C++]
14036 // A list item is a variable or array section, subject to the restrictions
14037 // specified in Section 2.4 on page 42 and in each of the sections
14038 // describing clauses and directives for which a list appears.
14039 // OpenMP [2.14.3.3, Restrictions, p.1]
14040 // A variable that is part of another variable (as an array or
14041 // structure element) cannot appear in a private clause.
14042 if (!FirstIter && IR != ER)
14043 ++IR;
14044 FirstIter = false;
14045 SourceLocation ELoc;
14046 SourceRange ERange;
14047 Expr *SimpleRefExpr = RefExpr;
14048 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
14049 /*AllowArraySection=*/true);
14050 if (Res.second) {
14051 // Try to find 'declare reduction' corresponding construct before using
14052 // builtin/overloaded operators.
14053 QualType Type = Context.DependentTy;
14054 CXXCastPath BasePath;
14055 ExprResult DeclareReductionRef = buildDeclareReductionRef(
14056 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
14057 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
14058 Expr *ReductionOp = nullptr;
14059 if (S.CurContext->isDependentContext() &&
14060 (DeclareReductionRef.isUnset() ||
14061 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
14062 ReductionOp = DeclareReductionRef.get();
14063 // It will be analyzed later.
14064 RD.push(RefExpr, ReductionOp);
14065 }
14066 ValueDecl *D = Res.first;
14067 if (!D)
14068 continue;
14069
14070 Expr *TaskgroupDescriptor = nullptr;
14071 QualType Type;
14072 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
14073 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
14074 if (ASE) {
14075 Type = ASE->getType().getNonReferenceType();
14076 } else if (OASE) {
14077 QualType BaseType =
14078 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
14079 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
14080 Type = ATy->getElementType();
14081 else
14082 Type = BaseType->getPointeeType();
14083 Type = Type.getNonReferenceType();
14084 } else {
14085 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
14086 }
14087 auto *VD = dyn_cast<VarDecl>(D);
14088
14089 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14090 // A variable that appears in a private clause must not have an incomplete
14091 // type or a reference type.
14092 if (S.RequireCompleteType(ELoc, D->getType(),
14093 diag::err_omp_reduction_incomplete_type))
14094 continue;
14095 // OpenMP [2.14.3.6, reduction clause, Restrictions]
14096 // A list item that appears in a reduction clause must not be
14097 // const-qualified.
14098 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
14099 /*AcceptIfMutable*/ false, ASE || OASE))
14100 continue;
14101
14102 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
14103 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
14104 // If a list-item is a reference type then it must bind to the same object
14105 // for all threads of the team.
14106 if (!ASE && !OASE) {
14107 if (VD) {
14108 VarDecl *VDDef = VD->getDefinition();
14109 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
14110 DSARefChecker Check(Stack);
14111 if (Check.Visit(VDDef->getInit())) {
14112 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
14113 << getOpenMPClauseName(ClauseKind) << ERange;
14114 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
14115 continue;
14116 }
14117 }
14118 }
14119
14120 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14121 // in a Construct]
14122 // Variables with the predetermined data-sharing attributes may not be
14123 // listed in data-sharing attributes clauses, except for the cases
14124 // listed below. For these exceptions only, listing a predetermined
14125 // variable in a data-sharing attribute clause is allowed and overrides
14126 // the variable's predetermined data-sharing attributes.
14127 // OpenMP [2.14.3.6, Restrictions, p.3]
14128 // Any number of reduction clauses can be specified on the directive,
14129 // but a list item can appear only once in the reduction clauses for that
14130 // directive.
14131 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
14132 if (DVar.CKind == OMPC_reduction) {
14133 S.Diag(ELoc, diag::err_omp_once_referenced)
14134 << getOpenMPClauseName(ClauseKind);
14135 if (DVar.RefExpr)
14136 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
14137 continue;
14138 }
14139 if (DVar.CKind != OMPC_unknown) {
14140 S.Diag(ELoc, diag::err_omp_wrong_dsa)
14141 << getOpenMPClauseName(DVar.CKind)
14142 << getOpenMPClauseName(OMPC_reduction);
14143 reportOriginalDsa(S, Stack, D, DVar);
14144 continue;
14145 }
14146
14147 // OpenMP [2.14.3.6, Restrictions, p.1]
14148 // A list item that appears in a reduction clause of a worksharing
14149 // construct must be shared in the parallel regions to which any of the
14150 // worksharing regions arising from the worksharing construct bind.
14151 if (isOpenMPWorksharingDirective(CurrDir) &&
14152 !isOpenMPParallelDirective(CurrDir) &&
14153 !isOpenMPTeamsDirective(CurrDir)) {
14154 DVar = Stack->getImplicitDSA(D, true);
14155 if (DVar.CKind != OMPC_shared) {
14156 S.Diag(ELoc, diag::err_omp_required_access)
14157 << getOpenMPClauseName(OMPC_reduction)
14158 << getOpenMPClauseName(OMPC_shared);
14159 reportOriginalDsa(S, Stack, D, DVar);
14160 continue;
14161 }
14162 }
14163 }
14164
14165 // Try to find 'declare reduction' corresponding construct before using
14166 // builtin/overloaded operators.
14167 CXXCastPath BasePath;
14168 ExprResult DeclareReductionRef = buildDeclareReductionRef(
14169 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
14170 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
14171 if (DeclareReductionRef.isInvalid())
14172 continue;
14173 if (S.CurContext->isDependentContext() &&
14174 (DeclareReductionRef.isUnset() ||
14175 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
14176 RD.push(RefExpr, DeclareReductionRef.get());
14177 continue;
14178 }
14179 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
14180 // Not allowed reduction identifier is found.
14181 S.Diag(ReductionId.getBeginLoc(),
14182 diag::err_omp_unknown_reduction_identifier)
14183 << Type << ReductionIdRange;
14184 continue;
14185 }
14186
14187 // OpenMP [2.14.3.6, reduction clause, Restrictions]
14188 // The type of a list item that appears in a reduction clause must be valid
14189 // for the reduction-identifier. For a max or min reduction in C, the type
14190 // of the list item must be an allowed arithmetic data type: char, int,
14191 // float, double, or _Bool, possibly modified with long, short, signed, or
14192 // unsigned. For a max or min reduction in C++, the type of the list item
14193 // must be an allowed arithmetic data type: char, wchar_t, int, float,
14194 // double, or bool, possibly modified with long, short, signed, or unsigned.
14195 if (DeclareReductionRef.isUnset()) {
14196 if ((BOK == BO_GT || BOK == BO_LT) &&
14197 !(Type->isScalarType() ||
14198 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
14199 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
14200 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
14201 if (!ASE && !OASE) {
14202 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14203 VarDecl::DeclarationOnly;
14204 S.Diag(D->getLocation(),
14205 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14206 << D;
14207 }
14208 continue;
14209 }
14210 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
14211 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
14212 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
14213 << getOpenMPClauseName(ClauseKind);
14214 if (!ASE && !OASE) {
14215 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14216 VarDecl::DeclarationOnly;
14217 S.Diag(D->getLocation(),
14218 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14219 << D;
14220 }
14221 continue;
14222 }
14223 }
14224
14225 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
14226 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
14227 D->hasAttrs() ? &D->getAttrs() : nullptr);
14228 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
14229 D->hasAttrs() ? &D->getAttrs() : nullptr);
14230 QualType PrivateTy = Type;
14231
14232 // Try if we can determine constant lengths for all array sections and avoid
14233 // the VLA.
14234 bool ConstantLengthOASE = false;
14235 if (OASE) {
14236 bool SingleElement;
14237 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
14238 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
14239 Context, OASE, SingleElement, ArraySizes);
14240
14241 // If we don't have a single element, we must emit a constant array type.
14242 if (ConstantLengthOASE && !SingleElement) {
14243 for (llvm::APSInt &Size : ArraySizes)
14244 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
14245 ArrayType::Normal,
14246 /*IndexTypeQuals=*/0);
14247 }
14248 }
14249
14250 if ((OASE && !ConstantLengthOASE) ||
14251 (!OASE && !ASE &&
14252 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
14253 if (!Context.getTargetInfo().isVLASupported()) {
14254 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
14255 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
14256 S.Diag(ELoc, diag::note_vla_unsupported);
14257 } else {
14258 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
14259 S.targetDiag(ELoc, diag::note_vla_unsupported);
14260 }
14261 continue;
14262 }
14263 // For arrays/array sections only:
14264 // Create pseudo array type for private copy. The size for this array will
14265 // be generated during codegen.
14266 // For array subscripts or single variables Private Ty is the same as Type
14267 // (type of the variable or single array element).
14268 PrivateTy = Context.getVariableArrayType(
14269 Type,
14270 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
14271 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
14272 } else if (!ASE && !OASE &&
14273 Context.getAsArrayType(D->getType().getNonReferenceType())) {
14274 PrivateTy = D->getType().getNonReferenceType();
14275 }
14276 // Private copy.
14277 VarDecl *PrivateVD =
14278 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
14279 D->hasAttrs() ? &D->getAttrs() : nullptr,
14280 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14281 // Add initializer for private variable.
14282 Expr *Init = nullptr;
14283 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
14284 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
14285 if (DeclareReductionRef.isUsable()) {
14286 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
14287 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
14288 if (DRD->getInitializer()) {
14289 Init = DRDRef;
14290 RHSVD->setInit(DRDRef);
14291 RHSVD->setInitStyle(VarDecl::CallInit);
14292 }
14293 } else {
14294 switch (BOK) {
14295 case BO_Add:
14296 case BO_Xor:
14297 case BO_Or:
14298 case BO_LOr:
14299 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
14300 if (Type->isScalarType() || Type->isAnyComplexType())
14301 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
14302 break;
14303 case BO_Mul:
14304 case BO_LAnd:
14305 if (Type->isScalarType() || Type->isAnyComplexType()) {
14306 // '*' and '&&' reduction ops - initializer is '1'.
14307 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
14308 }
14309 break;
14310 case BO_And: {
14311 // '&' reduction op - initializer is '~0'.
14312 QualType OrigType = Type;
14313 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
14314 Type = ComplexTy->getElementType();
14315 if (Type->isRealFloatingType()) {
14316 llvm::APFloat InitValue =
14317 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
14318 /*isIEEE=*/true);
14319 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
14320 Type, ELoc);
14321 } else if (Type->isScalarType()) {
14322 uint64_t Size = Context.getTypeSize(Type);
14323 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
14324 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
14325 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
14326 }
14327 if (Init && OrigType->isAnyComplexType()) {
14328 // Init = 0xFFFF + 0xFFFFi;
14329 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
14330 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
14331 }
14332 Type = OrigType;
14333 break;
14334 }
14335 case BO_LT:
14336 case BO_GT: {
14337 // 'min' reduction op - initializer is 'Largest representable number in
14338 // the reduction list item type'.
14339 // 'max' reduction op - initializer is 'Least representable number in
14340 // the reduction list item type'.
14341 if (Type->isIntegerType() || Type->isPointerType()) {
14342 bool IsSigned = Type->hasSignedIntegerRepresentation();
14343 uint64_t Size = Context.getTypeSize(Type);
14344 QualType IntTy =
14345 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
14346 llvm::APInt InitValue =
14347 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
14348 : llvm::APInt::getMinValue(Size)
14349 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
14350 : llvm::APInt::getMaxValue(Size);
14351 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
14352 if (Type->isPointerType()) {
14353 // Cast to pointer type.
14354 ExprResult CastExpr = S.BuildCStyleCastExpr(
14355 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
14356 if (CastExpr.isInvalid())
14357 continue;
14358 Init = CastExpr.get();
14359 }
14360 } else if (Type->isRealFloatingType()) {
14361 llvm::APFloat InitValue = llvm::APFloat::getLargest(
14362 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
14363 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
14364 Type, ELoc);
14365 }
14366 break;
14367 }
14368 case BO_PtrMemD:
14369 case BO_PtrMemI:
14370 case BO_MulAssign:
14371 case BO_Div:
14372 case BO_Rem:
14373 case BO_Sub:
14374 case BO_Shl:
14375 case BO_Shr:
14376 case BO_LE:
14377 case BO_GE:
14378 case BO_EQ:
14379 case BO_NE:
14380 case BO_Cmp:
14381 case BO_AndAssign:
14382 case BO_XorAssign:
14383 case BO_OrAssign:
14384 case BO_Assign:
14385 case BO_AddAssign:
14386 case BO_SubAssign:
14387 case BO_DivAssign:
14388 case BO_RemAssign:
14389 case BO_ShlAssign:
14390 case BO_ShrAssign:
14391 case BO_Comma:
14392 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14392)
;
14393 }
14394 }
14395 if (Init && DeclareReductionRef.isUnset())
14396 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
14397 else if (!Init)
14398 S.ActOnUninitializedDecl(RHSVD);
14399 if (RHSVD->isInvalidDecl())
14400 continue;
14401 if (!RHSVD->hasInit() &&
14402 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
14403 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
14404 << Type << ReductionIdRange;
14405 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14406 VarDecl::DeclarationOnly;
14407 S.Diag(D->getLocation(),
14408 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14409 << D;
14410 continue;
14411 }
14412 // Store initializer for single element in private copy. Will be used during
14413 // codegen.
14414 PrivateVD->setInit(RHSVD->getInit());
14415 PrivateVD->setInitStyle(RHSVD->getInitStyle());
14416 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
14417 ExprResult ReductionOp;
14418 if (DeclareReductionRef.isUsable()) {
14419 QualType RedTy = DeclareReductionRef.get()->getType();
14420 QualType PtrRedTy = Context.getPointerType(RedTy);
14421 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
14422 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
14423 if (!BasePath.empty()) {
14424 LHS = S.DefaultLvalueConversion(LHS.get());
14425 RHS = S.DefaultLvalueConversion(RHS.get());
14426 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
14427 CK_UncheckedDerivedToBase, LHS.get(),
14428 &BasePath, LHS.get()->getValueKind());
14429 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
14430 CK_UncheckedDerivedToBase, RHS.get(),
14431 &BasePath, RHS.get()->getValueKind());
14432 }
14433 FunctionProtoType::ExtProtoInfo EPI;
14434 QualType Params[] = {PtrRedTy, PtrRedTy};
14435 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
14436 auto *OVE = new (Context) OpaqueValueExpr(
14437 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
14438 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
14439 Expr *Args[] = {LHS.get(), RHS.get()};
14440 ReductionOp =
14441 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
14442 } else {
14443 ReductionOp = S.BuildBinOp(
14444 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
14445 if (ReductionOp.isUsable()) {
14446 if (BOK != BO_LT && BOK != BO_GT) {
14447 ReductionOp =
14448 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14449 BO_Assign, LHSDRE, ReductionOp.get());
14450 } else {
14451 auto *ConditionalOp = new (Context)
14452 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
14453 Type, VK_LValue, OK_Ordinary);
14454 ReductionOp =
14455 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14456 BO_Assign, LHSDRE, ConditionalOp);
14457 }
14458 if (ReductionOp.isUsable())
14459 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
14460 /*DiscardedValue*/ false);
14461 }
14462 if (!ReductionOp.isUsable())
14463 continue;
14464 }
14465
14466 // OpenMP [2.15.4.6, Restrictions, p.2]
14467 // A list item that appears in an in_reduction clause of a task construct
14468 // must appear in a task_reduction clause of a construct associated with a
14469 // taskgroup region that includes the participating task in its taskgroup
14470 // set. The construct associated with the innermost region that meets this
14471 // condition must specify the same reduction-identifier as the in_reduction
14472 // clause.
14473 if (ClauseKind == OMPC_in_reduction) {
14474 SourceRange ParentSR;
14475 BinaryOperatorKind ParentBOK;
14476 const Expr *ParentReductionOp;
14477 Expr *ParentBOKTD, *ParentReductionOpTD;
14478 DSAStackTy::DSAVarData ParentBOKDSA =
14479 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
14480 ParentBOKTD);
14481 DSAStackTy::DSAVarData ParentReductionOpDSA =
14482 Stack->getTopMostTaskgroupReductionData(
14483 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
14484 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
14485 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
14486 if (!IsParentBOK && !IsParentReductionOp) {
14487 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
14488 continue;
14489 }
14490 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
14491 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
14492 IsParentReductionOp) {
14493 bool EmitError = true;
14494 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
14495 llvm::FoldingSetNodeID RedId, ParentRedId;
14496 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
14497 DeclareReductionRef.get()->Profile(RedId, Context,
14498 /*Canonical=*/true);
14499 EmitError = RedId != ParentRedId;
14500 }
14501 if (EmitError) {
14502 S.Diag(ReductionId.getBeginLoc(),
14503 diag::err_omp_reduction_identifier_mismatch)
14504 << ReductionIdRange << RefExpr->getSourceRange();
14505 S.Diag(ParentSR.getBegin(),
14506 diag::note_omp_previous_reduction_identifier)
14507 << ParentSR
14508 << (IsParentBOK ? ParentBOKDSA.RefExpr
14509 : ParentReductionOpDSA.RefExpr)
14510 ->getSourceRange();
14511 continue;
14512 }
14513 }
14514 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
14515 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.")((TaskgroupDescriptor && "Taskgroup descriptor must be defined."
) ? static_cast<void> (0) : __assert_fail ("TaskgroupDescriptor && \"Taskgroup descriptor must be defined.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14515, __PRETTY_FUNCTION__))
;
14516 }
14517
14518 DeclRefExpr *Ref = nullptr;
14519 Expr *VarsExpr = RefExpr->IgnoreParens();
14520 if (!VD && !S.CurContext->isDependentContext()) {
14521 if (ASE || OASE) {
14522 TransformExprToCaptures RebuildToCapture(S, D);
14523 VarsExpr =
14524 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
14525 Ref = RebuildToCapture.getCapturedExpr();
14526 } else {
14527 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
14528 }
14529 if (!S.isOpenMPCapturedDecl(D)) {
14530 RD.ExprCaptures.emplace_back(Ref->getDecl());
14531 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
14532 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
14533 if (!RefRes.isUsable())
14534 continue;
14535 ExprResult PostUpdateRes =
14536 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14537 RefRes.get());
14538 if (!PostUpdateRes.isUsable())
14539 continue;
14540 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
14541 Stack->getCurrentDirective() == OMPD_taskgroup) {
14542 S.Diag(RefExpr->getExprLoc(),
14543 diag::err_omp_reduction_non_addressable_expression)
14544 << RefExpr->getSourceRange();
14545 continue;
14546 }
14547 RD.ExprPostUpdates.emplace_back(
14548 S.IgnoredValueConversions(PostUpdateRes.get()).get());
14549 }
14550 }
14551 }
14552 // All reduction items are still marked as reduction (to do not increase
14553 // code base size).
14554 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
14555 if (CurrDir == OMPD_taskgroup) {
14556 if (DeclareReductionRef.isUsable())
14557 Stack->addTaskgroupReductionData(D, ReductionIdRange,
14558 DeclareReductionRef.get());
14559 else
14560 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
14561 }
14562 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
14563 TaskgroupDescriptor);
14564 }
14565 return RD.Vars.empty();
14566}
14567
14568OMPClause *Sema::ActOnOpenMPReductionClause(
14569 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14570 SourceLocation ColonLoc, SourceLocation EndLoc,
14571 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14572 ArrayRef<Expr *> UnresolvedReductions) {
14573 ReductionData RD(VarList.size());
14574 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
14575 StartLoc, LParenLoc, ColonLoc, EndLoc,
14576 ReductionIdScopeSpec, ReductionId,
14577 UnresolvedReductions, RD))
14578 return nullptr;
14579
14580 return OMPReductionClause::Create(
14581 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14582 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14583 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14584 buildPreInits(Context, RD.ExprCaptures),
14585 buildPostUpdate(*this, RD.ExprPostUpdates));
14586}
14587
14588OMPClause *Sema::ActOnOpenMPTaskReductionClause(
14589 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14590 SourceLocation ColonLoc, SourceLocation EndLoc,
14591 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14592 ArrayRef<Expr *> UnresolvedReductions) {
14593 ReductionData RD(VarList.size());
14594 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction, VarList,
14595 StartLoc, LParenLoc, ColonLoc, EndLoc,
14596 ReductionIdScopeSpec, ReductionId,
14597 UnresolvedReductions, RD))
14598 return nullptr;
14599
14600 return OMPTaskReductionClause::Create(
14601 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14602 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14603 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14604 buildPreInits(Context, RD.ExprCaptures),
14605 buildPostUpdate(*this, RD.ExprPostUpdates));
14606}
14607
14608OMPClause *Sema::ActOnOpenMPInReductionClause(
14609 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14610 SourceLocation ColonLoc, SourceLocation EndLoc,
14611 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14612 ArrayRef<Expr *> UnresolvedReductions) {
14613 ReductionData RD(VarList.size());
14614 if (actOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
14615 StartLoc, LParenLoc, ColonLoc, EndLoc,
14616 ReductionIdScopeSpec, ReductionId,
14617 UnresolvedReductions, RD))
14618 return nullptr;
14619
14620 return OMPInReductionClause::Create(
14621 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14622 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14623 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
14624 buildPreInits(Context, RD.ExprCaptures),
14625 buildPostUpdate(*this, RD.ExprPostUpdates));
14626}
14627
14628bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
14629 SourceLocation LinLoc) {
14630 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
14631 LinKind == OMPC_LINEAR_unknown) {
14632 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
14633 return true;
14634 }
14635 return false;
14636}
14637
14638bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
14639 OpenMPLinearClauseKind LinKind, QualType Type,
14640 bool IsDeclareSimd) {
14641 const auto *VD = dyn_cast_or_null<VarDecl>(D);
14642 // A variable must not have an incomplete type or a reference type.
14643 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
14644 return true;
14645 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
14646 !Type->isReferenceType()) {
14647 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
14648 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
14649 return true;
14650 }
14651 Type = Type.getNonReferenceType();
14652
14653 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14654 // A variable that is privatized must not have a const-qualified type
14655 // unless it is of class type with a mutable member. This restriction does
14656 // not apply to the firstprivate clause, nor to the linear clause on
14657 // declarative directives (like declare simd).
14658 if (!IsDeclareSimd &&
14659 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
14660 return true;
14661
14662 // A list item must be of integral or pointer type.
14663 Type = Type.getUnqualifiedType().getCanonicalType();
14664 const auto *Ty = Type.getTypePtrOrNull();
14665 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
14666 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
14667 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
14668 if (D) {
14669 bool IsDecl =
14670 !VD ||
14671 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14672 Diag(D->getLocation(),
14673 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14674 << D;
14675 }
14676 return true;
14677 }
14678 return false;
14679}
14680
14681OMPClause *Sema::ActOnOpenMPLinearClause(
14682 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
14683 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
14684 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
14685 SmallVector<Expr *, 8> Vars;
14686 SmallVector<Expr *, 8> Privates;
14687 SmallVector<Expr *, 8> Inits;
14688 SmallVector<Decl *, 4> ExprCaptures;
14689 SmallVector<Expr *, 4> ExprPostUpdates;
14690 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
14691 LinKind = OMPC_LINEAR_val;
14692 for (Expr *RefExpr : VarList) {
14693 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14693, __PRETTY_FUNCTION__))
;
14694 SourceLocation ELoc;
14695 SourceRange ERange;
14696 Expr *SimpleRefExpr = RefExpr;
14697 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14698 if (Res.second) {
14699 // It will be analyzed later.
14700 Vars.push_back(RefExpr);
14701 Privates.push_back(nullptr);
14702 Inits.push_back(nullptr);
14703 }
14704 ValueDecl *D = Res.first;
14705 if (!D)
14706 continue;
14707
14708 QualType Type = D->getType();
14709 auto *VD = dyn_cast<VarDecl>(D);
14710
14711 // OpenMP [2.14.3.7, linear clause]
14712 // A list-item cannot appear in more than one linear clause.
14713 // A list-item that appears in a linear clause cannot appear in any
14714 // other data-sharing attribute clause.
14715 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
14716 if (DVar.RefExpr) {
14717 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14718 << getOpenMPClauseName(OMPC_linear);
14719 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
14720 continue;
14721 }
14722
14723 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
14724 continue;
14725 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
14726
14727 // Build private copy of original var.
14728 VarDecl *Private =
14729 buildVarDecl(*this, ELoc, Type, D->getName(),
14730 D->hasAttrs() ? &D->getAttrs() : nullptr,
14731 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14732 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
14733 // Build var to save initial value.
14734 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
14735 Expr *InitExpr;
14736 DeclRefExpr *Ref = nullptr;
14737 if (!VD && !CurContext->isDependentContext()) {
14738 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14739 if (!isOpenMPCapturedDecl(D)) {
14740 ExprCaptures.push_back(Ref->getDecl());
14741 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
14742 ExprResult RefRes = DefaultLvalueConversion(Ref);
14743 if (!RefRes.isUsable())
14744 continue;
14745 ExprResult PostUpdateRes =
14746 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
14747 SimpleRefExpr, RefRes.get());
14748 if (!PostUpdateRes.isUsable())
14749 continue;
14750 ExprPostUpdates.push_back(
14751 IgnoredValueConversions(PostUpdateRes.get()).get());
14752 }
14753 }
14754 }
14755 if (LinKind == OMPC_LINEAR_uval)
14756 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
14757 else
14758 InitExpr = VD ? SimpleRefExpr : Ref;
14759 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
14760 /*DirectInit=*/false);
14761 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
14762
14763 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
14764 Vars.push_back((VD || CurContext->isDependentContext())
14765 ? RefExpr->IgnoreParens()
14766 : Ref);
14767 Privates.push_back(PrivateRef);
14768 Inits.push_back(InitRef);
14769 }
14770
14771 if (Vars.empty())
14772 return nullptr;
14773
14774 Expr *StepExpr = Step;
14775 Expr *CalcStepExpr = nullptr;
14776 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
14777 !Step->isInstantiationDependent() &&
14778 !Step->containsUnexpandedParameterPack()) {
14779 SourceLocation StepLoc = Step->getBeginLoc();
14780 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
14781 if (Val.isInvalid())
14782 return nullptr;
14783 StepExpr = Val.get();
14784
14785 // Build var to save the step value.
14786 VarDecl *SaveVar =
14787 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
14788 ExprResult SaveRef =
14789 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
14790 ExprResult CalcStep =
14791 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
14792 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
14793
14794 // Warn about zero linear step (it would be probably better specified as
14795 // making corresponding variables 'const').
14796 llvm::APSInt Result;
14797 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
14798 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
14799 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
14800 << (Vars.size() > 1);
14801 if (!IsConstant && CalcStep.isUsable()) {
14802 // Calculate the step beforehand instead of doing this on each iteration.
14803 // (This is not used if the number of iterations may be kfold-ed).
14804 CalcStepExpr = CalcStep.get();
14805 }
14806 }
14807
14808 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
14809 ColonLoc, EndLoc, Vars, Privates, Inits,
14810 StepExpr, CalcStepExpr,
14811 buildPreInits(Context, ExprCaptures),
14812 buildPostUpdate(*this, ExprPostUpdates));
14813}
14814
14815static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
14816 Expr *NumIterations, Sema &SemaRef,
14817 Scope *S, DSAStackTy *Stack) {
14818 // Walk the vars and build update/final expressions for the CodeGen.
14819 SmallVector<Expr *, 8> Updates;
14820 SmallVector<Expr *, 8> Finals;
14821 SmallVector<Expr *, 8> UsedExprs;
14822 Expr *Step = Clause.getStep();
14823 Expr *CalcStep = Clause.getCalcStep();
14824 // OpenMP [2.14.3.7, linear clause]
14825 // If linear-step is not specified it is assumed to be 1.
14826 if (!Step)
14827 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
14828 else if (CalcStep)
14829 Step = cast<BinaryOperator>(CalcStep)->getLHS();
14830 bool HasErrors = false;
14831 auto CurInit = Clause.inits().begin();
14832 auto CurPrivate = Clause.privates().begin();
14833 OpenMPLinearClauseKind LinKind = Clause.getModifier();
14834 for (Expr *RefExpr : Clause.varlists()) {
14835 SourceLocation ELoc;
14836 SourceRange ERange;
14837 Expr *SimpleRefExpr = RefExpr;
14838 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
14839 ValueDecl *D = Res.first;
14840 if (Res.second || !D) {
14841 Updates.push_back(nullptr);
14842 Finals.push_back(nullptr);
14843 HasErrors = true;
14844 continue;
14845 }
14846 auto &&Info = Stack->isLoopControlVariable(D);
14847 // OpenMP [2.15.11, distribute simd Construct]
14848 // A list item may not appear in a linear clause, unless it is the loop
14849 // iteration variable.
14850 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
14851 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
14852 SemaRef.Diag(ELoc,
14853 diag::err_omp_linear_distribute_var_non_loop_iteration);
14854 Updates.push_back(nullptr);
14855 Finals.push_back(nullptr);
14856 HasErrors = true;
14857 continue;
14858 }
14859 Expr *InitExpr = *CurInit;
14860
14861 // Build privatized reference to the current linear var.
14862 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
14863 Expr *CapturedRef;
14864 if (LinKind == OMPC_LINEAR_uval)
14865 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
14866 else
14867 CapturedRef =
14868 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
14869 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
14870 /*RefersToCapture=*/true);
14871
14872 // Build update: Var = InitExpr + IV * Step
14873 ExprResult Update;
14874 if (!Info.first)
14875 Update = buildCounterUpdate(
14876 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
14877 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
14878 else
14879 Update = *CurPrivate;
14880 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
14881 /*DiscardedValue*/ false);
14882
14883 // Build final: Var = InitExpr + NumIterations * Step
14884 ExprResult Final;
14885 if (!Info.first)
14886 Final =
14887 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
14888 InitExpr, NumIterations, Step, /*Subtract=*/false,
14889 /*IsNonRectangularLB=*/false);
14890 else
14891 Final = *CurPrivate;
14892 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
14893 /*DiscardedValue*/ false);
14894
14895 if (!Update.isUsable() || !Final.isUsable()) {
14896 Updates.push_back(nullptr);
14897 Finals.push_back(nullptr);
14898 UsedExprs.push_back(nullptr);
14899 HasErrors = true;
14900 } else {
14901 Updates.push_back(Update.get());
14902 Finals.push_back(Final.get());
14903 if (!Info.first)
14904 UsedExprs.push_back(SimpleRefExpr);
14905 }
14906 ++CurInit;
14907 ++CurPrivate;
14908 }
14909 if (Expr *S = Clause.getStep())
14910 UsedExprs.push_back(S);
14911 // Fill the remaining part with the nullptr.
14912 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
14913 Clause.setUpdates(Updates);
14914 Clause.setFinals(Finals);
14915 Clause.setUsedExprs(UsedExprs);
14916 return HasErrors;
14917}
14918
14919OMPClause *Sema::ActOnOpenMPAlignedClause(
14920 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
14921 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
14922 SmallVector<Expr *, 8> Vars;
14923 for (Expr *RefExpr : VarList) {
14924 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 14924, __PRETTY_FUNCTION__))
;
14925 SourceLocation ELoc;
14926 SourceRange ERange;
14927 Expr *SimpleRefExpr = RefExpr;
14928 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14929 if (Res.second) {
14930 // It will be analyzed later.
14931 Vars.push_back(RefExpr);
14932 }
14933 ValueDecl *D = Res.first;
14934 if (!D)
14935 continue;
14936
14937 QualType QType = D->getType();
14938 auto *VD = dyn_cast<VarDecl>(D);
14939
14940 // OpenMP [2.8.1, simd construct, Restrictions]
14941 // The type of list items appearing in the aligned clause must be
14942 // array, pointer, reference to array, or reference to pointer.
14943 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
14944 const Type *Ty = QType.getTypePtrOrNull();
14945 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
14946 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
14947 << QType << getLangOpts().CPlusPlus << ERange;
14948 bool IsDecl =
14949 !VD ||
14950 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14951 Diag(D->getLocation(),
14952 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14953 << D;
14954 continue;
14955 }
14956
14957 // OpenMP [2.8.1, simd construct, Restrictions]
14958 // A list-item cannot appear in more than one aligned clause.
14959 if (const Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
14960 Diag(ELoc, diag::err_omp_used_in_clause_twice)
14961 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
14962 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
14963 << getOpenMPClauseName(OMPC_aligned);
14964 continue;
14965 }
14966
14967 DeclRefExpr *Ref = nullptr;
14968 if (!VD && isOpenMPCapturedDecl(D))
14969 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14970 Vars.push_back(DefaultFunctionArrayConversion(
14971 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
14972 .get());
14973 }
14974
14975 // OpenMP [2.8.1, simd construct, Description]
14976 // The parameter of the aligned clause, alignment, must be a constant
14977 // positive integer expression.
14978 // If no optional parameter is specified, implementation-defined default
14979 // alignments for SIMD instructions on the target platforms are assumed.
14980 if (Alignment != nullptr) {
14981 ExprResult AlignResult =
14982 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
14983 if (AlignResult.isInvalid())
14984 return nullptr;
14985 Alignment = AlignResult.get();
14986 }
14987 if (Vars.empty())
14988 return nullptr;
14989
14990 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
14991 EndLoc, Vars, Alignment);
14992}
14993
14994OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
14995 SourceLocation StartLoc,
14996 SourceLocation LParenLoc,
14997 SourceLocation EndLoc) {
14998 SmallVector<Expr *, 8> Vars;
14999 SmallVector<Expr *, 8> SrcExprs;
15000 SmallVector<Expr *, 8> DstExprs;
15001 SmallVector<Expr *, 8> AssignmentOps;
15002 for (Expr *RefExpr : VarList) {
15003 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15003, __PRETTY_FUNCTION__))
;
15004 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
15005 // It will be analyzed later.
15006 Vars.push_back(RefExpr);
15007 SrcExprs.push_back(nullptr);
15008 DstExprs.push_back(nullptr);
15009 AssignmentOps.push_back(nullptr);
15010 continue;
15011 }
15012
15013 SourceLocation ELoc = RefExpr->getExprLoc();
15014 // OpenMP [2.1, C/C++]
15015 // A list item is a variable name.
15016 // OpenMP [2.14.4.1, Restrictions, p.1]
15017 // A list item that appears in a copyin clause must be threadprivate.
15018 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
15019 if (!DE || !isa<VarDecl>(DE->getDecl())) {
15020 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
15021 << 0 << RefExpr->getSourceRange();
15022 continue;
15023 }
15024
15025 Decl *D = DE->getDecl();
15026 auto *VD = cast<VarDecl>(D);
15027
15028 QualType Type = VD->getType();
15029 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
15030 // It will be analyzed later.
15031 Vars.push_back(DE);
15032 SrcExprs.push_back(nullptr);
15033 DstExprs.push_back(nullptr);
15034 AssignmentOps.push_back(nullptr);
15035 continue;
15036 }
15037
15038 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
15039 // A list item that appears in a copyin clause must be threadprivate.
15040 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
15041 Diag(ELoc, diag::err_omp_required_access)
15042 << getOpenMPClauseName(OMPC_copyin)
15043 << getOpenMPDirectiveName(OMPD_threadprivate);
15044 continue;
15045 }
15046
15047 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
15048 // A variable of class type (or array thereof) that appears in a
15049 // copyin clause requires an accessible, unambiguous copy assignment
15050 // operator for the class type.
15051 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15052 VarDecl *SrcVD =
15053 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
15054 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
15055 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
15056 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
15057 VarDecl *DstVD =
15058 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
15059 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
15060 DeclRefExpr *PseudoDstExpr =
15061 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
15062 // For arrays generate assignment operation for single element and replace
15063 // it by the original array element in CodeGen.
15064 ExprResult AssignmentOp =
15065 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
15066 PseudoSrcExpr);
15067 if (AssignmentOp.isInvalid())
15068 continue;
15069 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
15070 /*DiscardedValue*/ false);
15071 if (AssignmentOp.isInvalid())
15072 continue;
15073
15074 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
15075 Vars.push_back(DE);
15076 SrcExprs.push_back(PseudoSrcExpr);
15077 DstExprs.push_back(PseudoDstExpr);
15078 AssignmentOps.push_back(AssignmentOp.get());
15079 }
15080
15081 if (Vars.empty())
15082 return nullptr;
15083
15084 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15085 SrcExprs, DstExprs, AssignmentOps);
15086}
15087
15088OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
15089 SourceLocation StartLoc,
15090 SourceLocation LParenLoc,
15091 SourceLocation EndLoc) {
15092 SmallVector<Expr *, 8> Vars;
15093 SmallVector<Expr *, 8> SrcExprs;
15094 SmallVector<Expr *, 8> DstExprs;
15095 SmallVector<Expr *, 8> AssignmentOps;
15096 for (Expr *RefExpr : VarList) {
15097 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15097, __PRETTY_FUNCTION__))
;
15098 SourceLocation ELoc;
15099 SourceRange ERange;
15100 Expr *SimpleRefExpr = RefExpr;
15101 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15102 if (Res.second) {
15103 // It will be analyzed later.
15104 Vars.push_back(RefExpr);
15105 SrcExprs.push_back(nullptr);
15106 DstExprs.push_back(nullptr);
15107 AssignmentOps.push_back(nullptr);
15108 }
15109 ValueDecl *D = Res.first;
15110 if (!D)
15111 continue;
15112
15113 QualType Type = D->getType();
15114 auto *VD = dyn_cast<VarDecl>(D);
15115
15116 // OpenMP [2.14.4.2, Restrictions, p.2]
15117 // A list item that appears in a copyprivate clause may not appear in a
15118 // private or firstprivate clause on the single construct.
15119 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
15120 DSAStackTy::DSAVarData DVar =
15121 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
15122 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
15123 DVar.RefExpr) {
15124 Diag(ELoc, diag::err_omp_wrong_dsa)
15125 << getOpenMPClauseName(DVar.CKind)
15126 << getOpenMPClauseName(OMPC_copyprivate);
15127 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15128 continue;
15129 }
15130
15131 // OpenMP [2.11.4.2, Restrictions, p.1]
15132 // All list items that appear in a copyprivate clause must be either
15133 // threadprivate or private in the enclosing context.
15134 if (DVar.CKind == OMPC_unknown) {
15135 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
15136 if (DVar.CKind == OMPC_shared) {
15137 Diag(ELoc, diag::err_omp_required_access)
15138 << getOpenMPClauseName(OMPC_copyprivate)
15139 << "threadprivate or private in the enclosing context";
15140 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
15141 continue;
15142 }
15143 }
15144 }
15145
15146 // Variably modified types are not supported.
15147 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
15148 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15149 << getOpenMPClauseName(OMPC_copyprivate) << Type
15150 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
15151 bool IsDecl =
15152 !VD ||
15153 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15154 Diag(D->getLocation(),
15155 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15156 << D;
15157 continue;
15158 }
15159
15160 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
15161 // A variable of class type (or array thereof) that appears in a
15162 // copyin clause requires an accessible, unambiguous copy assignment
15163 // operator for the class type.
15164 Type = Context.getBaseElementType(Type.getNonReferenceType())
15165 .getUnqualifiedType();
15166 VarDecl *SrcVD =
15167 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
15168 D->hasAttrs() ? &D->getAttrs() : nullptr);
15169 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
15170 VarDecl *DstVD =
15171 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
15172 D->hasAttrs() ? &D->getAttrs() : nullptr);
15173 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
15174 ExprResult AssignmentOp = BuildBinOp(
15175 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
15176 if (AssignmentOp.isInvalid())
15177 continue;
15178 AssignmentOp =
15179 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
15180 if (AssignmentOp.isInvalid())
15181 continue;
15182
15183 // No need to mark vars as copyprivate, they are already threadprivate or
15184 // implicitly private.
15185 assert(VD || isOpenMPCapturedDecl(D))((VD || isOpenMPCapturedDecl(D)) ? static_cast<void> (0
) : __assert_fail ("VD || isOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15185, __PRETTY_FUNCTION__))
;
15186 Vars.push_back(
15187 VD ? RefExpr->IgnoreParens()
15188 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
15189 SrcExprs.push_back(PseudoSrcExpr);
15190 DstExprs.push_back(PseudoDstExpr);
15191 AssignmentOps.push_back(AssignmentOp.get());
15192 }
15193
15194 if (Vars.empty())
15195 return nullptr;
15196
15197 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15198 Vars, SrcExprs, DstExprs, AssignmentOps);
15199}
15200
15201OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
15202 SourceLocation StartLoc,
15203 SourceLocation LParenLoc,
15204 SourceLocation EndLoc) {
15205 if (VarList.empty())
15206 return nullptr;
15207
15208 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
15209}
15210
15211/// Tries to find omp_depend_t. type.
15212static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
15213 bool Diagnose = true) {
15214 QualType OMPDependT = Stack->getOMPDependT();
15215 if (!OMPDependT.isNull())
15216 return true;
15217 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
15218 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
15219 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
15220 if (Diagnose)
15221 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
15222 return false;
15223 }
15224 Stack->setOMPDependT(PT.get());
15225 return true;
15226}
15227
15228OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
15229 SourceLocation LParenLoc,
15230 SourceLocation EndLoc) {
15231 if (!Depobj)
15232 return nullptr;
15233
15234 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
);
15235
15236 // OpenMP 5.0, 2.17.10.1 depobj Construct
15237 // depobj is an lvalue expression of type omp_depend_t.
15238 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
15239 !Depobj->isInstantiationDependent() &&
15240 !Depobj->containsUnexpandedParameterPack() &&
15241 (OMPDependTFound &&
15242 !Context.typesAreCompatible(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(), Depobj->getType(),
15243 /*CompareUnqualified=*/true))) {
15244 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
15245 << 0 << Depobj->getType() << Depobj->getSourceRange();
15246 }
15247
15248 if (!Depobj->isLValue()) {
15249 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
15250 << 1 << Depobj->getSourceRange();
15251 }
15252
15253 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
15254}
15255
15256OMPClause *
15257Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
15258 SourceLocation DepLoc, SourceLocation ColonLoc,
15259 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
15260 SourceLocation LParenLoc, SourceLocation EndLoc) {
15261 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
15262 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
15263 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
15264 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
15265 return nullptr;
15266 }
15267 if ((DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered ||
15268 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
15269 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
15270 DepKind == OMPC_DEPEND_sink ||
15271 ((LangOpts.OpenMP < 50 ||
15272 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj) &&
15273 DepKind == OMPC_DEPEND_depobj))) {
15274 SmallVector<unsigned, 3> Except;
15275 Except.push_back(OMPC_DEPEND_source);
15276 Except.push_back(OMPC_DEPEND_sink);
15277 if (LangOpts.OpenMP < 50 || DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_depobj)
15278 Except.push_back(OMPC_DEPEND_depobj);
15279 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
15280 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
15281 /*Last=*/OMPC_DEPEND_unknown, Except)
15282 << getOpenMPClauseName(OMPC_depend);
15283 return nullptr;
15284 }
15285 SmallVector<Expr *, 8> Vars;
15286 DSAStackTy::OperatorOffsetTy OpsOffs;
15287 llvm::APSInt DepCounter(/*BitWidth=*/32);
15288 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
15289 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
15290 if (const Expr *OrderedCountExpr =
15291 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first) {
15292 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
15293 TotalDepCount.setIsUnsigned(/*Val=*/true);
15294 }
15295 }
15296 for (Expr *RefExpr : VarList) {
15297 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15297, __PRETTY_FUNCTION__))
;
15298 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
15299 // It will be analyzed later.
15300 Vars.push_back(RefExpr);
15301 continue;
15302 }
15303
15304 SourceLocation ELoc = RefExpr->getExprLoc();
15305 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
15306 if (DepKind == OMPC_DEPEND_sink) {
15307 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
15308 DepCounter >= TotalDepCount) {
15309 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
15310 continue;
15311 }
15312 ++DepCounter;
15313 // OpenMP [2.13.9, Summary]
15314 // depend(dependence-type : vec), where dependence-type is:
15315 // 'sink' and where vec is the iteration vector, which has the form:
15316 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
15317 // where n is the value specified by the ordered clause in the loop
15318 // directive, xi denotes the loop iteration variable of the i-th nested
15319 // loop associated with the loop directive, and di is a constant
15320 // non-negative integer.
15321 if (CurContext->isDependentContext()) {
15322 // It will be analyzed later.
15323 Vars.push_back(RefExpr);
15324 continue;
15325 }
15326 SimpleExpr = SimpleExpr->IgnoreImplicit();
15327 OverloadedOperatorKind OOK = OO_None;
15328 SourceLocation OOLoc;
15329 Expr *LHS = SimpleExpr;
15330 Expr *RHS = nullptr;
15331 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
15332 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
15333 OOLoc = BO->getOperatorLoc();
15334 LHS = BO->getLHS()->IgnoreParenImpCasts();
15335 RHS = BO->getRHS()->IgnoreParenImpCasts();
15336 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
15337 OOK = OCE->getOperator();
15338 OOLoc = OCE->getOperatorLoc();
15339 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
15340 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
15341 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
15342 OOK = MCE->getMethodDecl()
15343 ->getNameInfo()
15344 .getName()
15345 .getCXXOverloadedOperator();
15346 OOLoc = MCE->getCallee()->getExprLoc();
15347 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
15348 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
15349 }
15350 SourceLocation ELoc;
15351 SourceRange ERange;
15352 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
15353 if (Res.second) {
15354 // It will be analyzed later.
15355 Vars.push_back(RefExpr);
15356 }
15357 ValueDecl *D = Res.first;
15358 if (!D)
15359 continue;
15360
15361 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
15362 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
15363 continue;
15364 }
15365 if (RHS) {
15366 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
15367 RHS, OMPC_depend, /*StrictlyPositive=*/false);
15368 if (RHSRes.isInvalid())
15369 continue;
15370 }
15371 if (!CurContext->isDependentContext() &&
15372 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
15373 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
15374 const ValueDecl *VD =
15375 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
15376 if (VD)
15377 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
15378 << 1 << VD;
15379 else
15380 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
15381 continue;
15382 }
15383 OpsOffs.emplace_back(RHS, OOK);
15384 } else {
15385 bool OMPDependTFound = LangOpts.OpenMP >= 50;
15386 if (OMPDependTFound)
15387 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
15388 DepKind == OMPC_DEPEND_depobj);
15389 if (DepKind == OMPC_DEPEND_depobj) {
15390 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
15391 // List items used in depend clauses with the depobj dependence type
15392 // must be expressions of the omp_depend_t type.
15393 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
15394 !RefExpr->isInstantiationDependent() &&
15395 !RefExpr->containsUnexpandedParameterPack() &&
15396 (OMPDependTFound &&
15397 !Context.hasSameUnqualifiedType(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT(),
15398 RefExpr->getType()))) {
15399 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
15400 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
15401 continue;
15402 }
15403 if (!RefExpr->isLValue()) {
15404 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
15405 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
15406 continue;
15407 }
15408 } else {
15409 // OpenMP 5.0 [2.17.11, Restrictions]
15410 // List items used in depend clauses cannot be zero-length array
15411 // sections.
15412 QualType ExprTy = RefExpr->getType().getNonReferenceType();
15413 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
15414 if (OASE) {
15415 QualType BaseType =
15416 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
15417 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
15418 ExprTy = ATy->getElementType();
15419 else
15420 ExprTy = BaseType->getPointeeType();
15421 ExprTy = ExprTy.getNonReferenceType();
15422 const Expr *Length = OASE->getLength();
15423 Expr::EvalResult Result;
15424 if (Length && !Length->isValueDependent() &&
15425 Length->EvaluateAsInt(Result, Context) &&
15426 Result.Val.getInt().isNullValue()) {
15427 Diag(ELoc,
15428 diag::err_omp_depend_zero_length_array_section_not_allowed)
15429 << SimpleExpr->getSourceRange();
15430 continue;
15431 }
15432 }
15433
15434 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
15435 // List items used in depend clauses with the in, out, inout or
15436 // mutexinoutset dependence types cannot be expressions of the
15437 // omp_depend_t type.
15438 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
15439 !RefExpr->isInstantiationDependent() &&
15440 !RefExpr->containsUnexpandedParameterPack() &&
15441 (OMPDependTFound &&
15442 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
15443 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15444 << 1 << RefExpr->getSourceRange();
15445 continue;
15446 }
15447
15448 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
15449 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
15450 (ASE &&
15451 !ASE->getBase()
15452 ->getType()
15453 .getNonReferenceType()
15454 ->isPointerType() &&
15455 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
15456 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15457 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
15458 continue;
15459 }
15460
15461 ExprResult Res;
15462 {
15463 Sema::TentativeAnalysisScope Trap(*this);
15464 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
15465 RefExpr->IgnoreParenImpCasts());
15466 }
15467 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
15468 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15469 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
15470 continue;
15471 }
15472 }
15473 }
15474 Vars.push_back(RefExpr->IgnoreParenImpCasts());
15475 }
15476
15477 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
15478 TotalDepCount > VarList.size() &&
15479 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam().first &&
15480 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
15481 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
15482 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
15483 }
15484 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
15485 Vars.empty())
15486 return nullptr;
15487
15488 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15489 DepKind, DepLoc, ColonLoc, Vars,
15490 TotalDepCount.getZExtValue());
15491 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
15492 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
15493 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
15494 return C;
15495}
15496
15497OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
15498 SourceLocation LParenLoc,
15499 SourceLocation EndLoc) {
15500 Expr *ValExpr = Device;
15501 Stmt *HelperValStmt = nullptr;
15502
15503 // OpenMP [2.9.1, Restrictions]
15504 // The device expression must evaluate to a non-negative integer value.
15505 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
15506 /*StrictlyPositive=*/false))
15507 return nullptr;
15508
15509 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
15510 OpenMPDirectiveKind CaptureRegion =
15511 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
15512 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15513 ValExpr = MakeFullExpr(ValExpr).get();
15514 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15515 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15516 HelperValStmt = buildPreInits(Context, Captures);
15517 }
15518
15519 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
15520 StartLoc, LParenLoc, EndLoc);
15521}
15522
15523static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
15524 DSAStackTy *Stack, QualType QTy,
15525 bool FullCheck = true) {
15526 NamedDecl *ND;
15527 if (QTy->isIncompleteType(&ND)) {
15528 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
15529 return false;
15530 }
15531 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
15532 !QTy.isTriviallyCopyableType(SemaRef.Context))
15533 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
15534 return true;
15535}
15536
15537/// Return true if it can be proven that the provided array expression
15538/// (array section or array subscript) does NOT specify the whole size of the
15539/// array whose base type is \a BaseQTy.
15540static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
15541 const Expr *E,
15542 QualType BaseQTy) {
15543 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
15544
15545 // If this is an array subscript, it refers to the whole size if the size of
15546 // the dimension is constant and equals 1. Also, an array section assumes the
15547 // format of an array subscript if no colon is used.
15548 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
15549 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
15550 return ATy->getSize().getSExtValue() != 1;
15551 // Size can't be evaluated statically.
15552 return false;
15553 }
15554
15555 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15555, __PRETTY_FUNCTION__))
;
15556 const Expr *LowerBound = OASE->getLowerBound();
15557 const Expr *Length = OASE->getLength();
15558
15559 // If there is a lower bound that does not evaluates to zero, we are not
15560 // covering the whole dimension.
15561 if (LowerBound) {
15562 Expr::EvalResult Result;
15563 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
15564 return false; // Can't get the integer value as a constant.
15565
15566 llvm::APSInt ConstLowerBound = Result.Val.getInt();
15567 if (ConstLowerBound.getSExtValue())
15568 return true;
15569 }
15570
15571 // If we don't have a length we covering the whole dimension.
15572 if (!Length)
15573 return false;
15574
15575 // If the base is a pointer, we don't have a way to get the size of the
15576 // pointee.
15577 if (BaseQTy->isPointerType())
15578 return false;
15579
15580 // We can only check if the length is the same as the size of the dimension
15581 // if we have a constant array.
15582 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
15583 if (!CATy)
15584 return false;
15585
15586 Expr::EvalResult Result;
15587 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
15588 return false; // Can't get the integer value as a constant.
15589
15590 llvm::APSInt ConstLength = Result.Val.getInt();
15591 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
15592}
15593
15594// Return true if it can be proven that the provided array expression (array
15595// section or array subscript) does NOT specify a single element of the array
15596// whose base type is \a BaseQTy.
15597static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
15598 const Expr *E,
15599 QualType BaseQTy) {
15600 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
15601
15602 // An array subscript always refer to a single element. Also, an array section
15603 // assumes the format of an array subscript if no colon is used.
15604 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
15605 return false;
15606
15607 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15607, __PRETTY_FUNCTION__))
;
15608 const Expr *Length = OASE->getLength();
15609
15610 // If we don't have a length we have to check if the array has unitary size
15611 // for this dimension. Also, we should always expect a length if the base type
15612 // is pointer.
15613 if (!Length) {
15614 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
15615 return ATy->getSize().getSExtValue() != 1;
15616 // We cannot assume anything.
15617 return false;
15618 }
15619
15620 // Check if the length evaluates to 1.
15621 Expr::EvalResult Result;
15622 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
15623 return false; // Can't get the integer value as a constant.
15624
15625 llvm::APSInt ConstLength = Result.Val.getInt();
15626 return ConstLength.getSExtValue() != 1;
15627}
15628
15629// The base of elements of list in a map clause have to be either:
15630// - a reference to variable or field.
15631// - a member expression.
15632// - an array expression.
15633//
15634// E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
15635// reference to 'r'.
15636//
15637// If we have:
15638//
15639// struct SS {
15640// Bla S;
15641// foo() {
15642// #pragma omp target map (S.Arr[:12]);
15643// }
15644// }
15645//
15646// We want to retrieve the member expression 'this->S';
15647
15648// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
15649// If a list item is an array section, it must specify contiguous storage.
15650//
15651// For this restriction it is sufficient that we make sure only references
15652// to variables or fields and array expressions, and that no array sections
15653// exist except in the rightmost expression (unless they cover the whole
15654// dimension of the array). E.g. these would be invalid:
15655//
15656// r.ArrS[3:5].Arr[6:7]
15657//
15658// r.ArrS[3:5].x
15659//
15660// but these would be valid:
15661// r.ArrS[3].Arr[6:7]
15662//
15663// r.ArrS[3].x
15664namespace {
15665class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
15666 Sema &SemaRef;
15667 OpenMPClauseKind CKind = OMPC_unknown;
15668 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
15669 bool NoDiagnose = false;
15670 const Expr *RelevantExpr = nullptr;
15671 bool AllowUnitySizeArraySection = true;
15672 bool AllowWholeSizeArraySection = true;
15673 SourceLocation ELoc;
15674 SourceRange ERange;
15675
15676 void emitErrorMsg() {
15677 // If nothing else worked, this is not a valid map clause expression.
15678 if (SemaRef.getLangOpts().OpenMP < 50) {
15679 SemaRef.Diag(ELoc,
15680 diag::err_omp_expected_named_var_member_or_array_expression)
15681 << ERange;
15682 } else {
15683 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
15684 << getOpenMPClauseName(CKind) << ERange;
15685 }
15686 }
15687
15688public:
15689 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
15690 if (!isa<VarDecl>(DRE->getDecl())) {
15691 emitErrorMsg();
15692 return false;
15693 }
15694 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15694, __PRETTY_FUNCTION__))
;
15695 RelevantExpr = DRE;
15696 // Record the component.
15697 Components.emplace_back(DRE, DRE->getDecl());
15698 return true;
15699 }
15700
15701 bool VisitMemberExpr(MemberExpr *ME) {
15702 Expr *E = ME;
15703 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
15704
15705 if (isa<CXXThisExpr>(BaseE)) {
15706 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15706, __PRETTY_FUNCTION__))
;
15707 // We found a base expression: this->Val.
15708 RelevantExpr = ME;
15709 } else {
15710 E = BaseE;
15711 }
15712
15713 if (!isa<FieldDecl>(ME->getMemberDecl())) {
15714 if (!NoDiagnose) {
15715 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
15716 << ME->getSourceRange();
15717 return false;
15718 }
15719 if (RelevantExpr)
15720 return false;
15721 return Visit(E);
15722 }
15723
15724 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
15725
15726 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
15727 // A bit-field cannot appear in a map clause.
15728 //
15729 if (FD->isBitField()) {
15730 if (!NoDiagnose) {
15731 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
15732 << ME->getSourceRange() << getOpenMPClauseName(CKind);
15733 return false;
15734 }
15735 if (RelevantExpr)
15736 return false;
15737 return Visit(E);
15738 }
15739
15740 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15741 // If the type of a list item is a reference to a type T then the type
15742 // will be considered to be T for all purposes of this clause.
15743 QualType CurType = BaseE->getType().getNonReferenceType();
15744
15745 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
15746 // A list item cannot be a variable that is a member of a structure with
15747 // a union type.
15748 //
15749 if (CurType->isUnionType()) {
15750 if (!NoDiagnose) {
15751 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
15752 << ME->getSourceRange();
15753 return false;
15754 }
15755 return RelevantExpr || Visit(E);
15756 }
15757
15758 // If we got a member expression, we should not expect any array section
15759 // before that:
15760 //
15761 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
15762 // If a list item is an element of a structure, only the rightmost symbol
15763 // of the variable reference can be an array section.
15764 //
15765 AllowUnitySizeArraySection = false;
15766 AllowWholeSizeArraySection = false;
15767
15768 // Record the component.
15769 Components.emplace_back(ME, FD);
15770 return RelevantExpr || Visit(E);
15771 }
15772
15773 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
15774 Expr *E = AE->getBase()->IgnoreParenImpCasts();
15775
15776 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
15777 if (!NoDiagnose) {
15778 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
15779 << 0 << AE->getSourceRange();
15780 return false;
15781 }
15782 return RelevantExpr || Visit(E);
15783 }
15784
15785 // If we got an array subscript that express the whole dimension we
15786 // can have any array expressions before. If it only expressing part of
15787 // the dimension, we can only have unitary-size array expressions.
15788 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
15789 E->getType()))
15790 AllowWholeSizeArraySection = false;
15791
15792 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
15793 Expr::EvalResult Result;
15794 if (!AE->getIdx()->isValueDependent() &&
15795 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
15796 !Result.Val.getInt().isNullValue()) {
15797 SemaRef.Diag(AE->getIdx()->getExprLoc(),
15798 diag::err_omp_invalid_map_this_expr);
15799 SemaRef.Diag(AE->getIdx()->getExprLoc(),
15800 diag::note_omp_invalid_subscript_on_this_ptr_map);
15801 }
15802 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15802, __PRETTY_FUNCTION__))
;
15803 RelevantExpr = TE;
15804 }
15805
15806 // Record the component - we don't have any declaration associated.
15807 Components.emplace_back(AE, nullptr);
15808
15809 return RelevantExpr || Visit(E);
15810 }
15811
15812 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
15813 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15813, __PRETTY_FUNCTION__))
;
15814 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
15815 QualType CurType =
15816 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
15817
15818 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15819 // If the type of a list item is a reference to a type T then the type
15820 // will be considered to be T for all purposes of this clause.
15821 if (CurType->isReferenceType())
15822 CurType = CurType->getPointeeType();
15823
15824 bool IsPointer = CurType->isAnyPointerType();
15825
15826 if (!IsPointer && !CurType->isArrayType()) {
15827 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
15828 << 0 << OASE->getSourceRange();
15829 return false;
15830 }
15831
15832 bool NotWhole =
15833 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
15834 bool NotUnity =
15835 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
15836
15837 if (AllowWholeSizeArraySection) {
15838 // Any array section is currently allowed. Allowing a whole size array
15839 // section implies allowing a unity array section as well.
15840 //
15841 // If this array section refers to the whole dimension we can still
15842 // accept other array sections before this one, except if the base is a
15843 // pointer. Otherwise, only unitary sections are accepted.
15844 if (NotWhole || IsPointer)
15845 AllowWholeSizeArraySection = false;
15846 } else if (AllowUnitySizeArraySection && NotUnity) {
15847 // A unity or whole array section is not allowed and that is not
15848 // compatible with the properties of the current array section.
15849 SemaRef.Diag(
15850 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
15851 << OASE->getSourceRange();
15852 return false;
15853 }
15854
15855 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
15856 Expr::EvalResult ResultR;
15857 Expr::EvalResult ResultL;
15858 if (!OASE->getLength()->isValueDependent() &&
15859 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
15860 !ResultR.Val.getInt().isOneValue()) {
15861 SemaRef.Diag(OASE->getLength()->getExprLoc(),
15862 diag::err_omp_invalid_map_this_expr);
15863 SemaRef.Diag(OASE->getLength()->getExprLoc(),
15864 diag::note_omp_invalid_length_on_this_ptr_mapping);
15865 }
15866 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
15867 OASE->getLowerBound()->EvaluateAsInt(ResultL,
15868 SemaRef.getASTContext()) &&
15869 !ResultL.Val.getInt().isNullValue()) {
15870 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
15871 diag::err_omp_invalid_map_this_expr);
15872 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
15873 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
15874 }
15875 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15875, __PRETTY_FUNCTION__))
;
15876 RelevantExpr = TE;
15877 }
15878
15879 // Record the component - we don't have any declaration associated.
15880 Components.emplace_back(OASE, nullptr);
15881 return RelevantExpr || Visit(E);
15882 }
15883 bool VisitUnaryOperator(UnaryOperator *UO) {
15884 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
15885 UO->getOpcode() != UO_Deref) {
15886 emitErrorMsg();
15887 return false;
15888 }
15889 if (!RelevantExpr) {
15890 // Record the component if haven't found base decl.
15891 Components.emplace_back(UO, nullptr);
15892 }
15893 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
15894 }
15895 bool VisitBinaryOperator(BinaryOperator *BO) {
15896 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
15897 emitErrorMsg();
15898 return false;
15899 }
15900
15901 // Pointer arithmetic is the only thing we expect to happen here so after we
15902 // make sure the binary operator is a pointer type, the we only thing need
15903 // to to is to visit the subtree that has the same type as root (so that we
15904 // know the other subtree is just an offset)
15905 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
15906 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
15907 Components.emplace_back(BO, nullptr);
15908 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15910, __PRETTY_FUNCTION__))
15909 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15910, __PRETTY_FUNCTION__))
15910 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15910, __PRETTY_FUNCTION__))
;
15911 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
15912 return RelevantExpr || Visit(LE);
15913 return RelevantExpr || Visit(RE);
15914 }
15915 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
15916 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15916, __PRETTY_FUNCTION__))
;
15917 RelevantExpr = CTE;
15918 Components.emplace_back(CTE, nullptr);
15919 return true;
15920 }
15921 bool VisitStmt(Stmt *) {
15922 emitErrorMsg();
15923 return false;
15924 }
15925 const Expr *getFoundBase() const {
15926 return RelevantExpr;
15927 }
15928 explicit MapBaseChecker(
15929 Sema &SemaRef, OpenMPClauseKind CKind,
15930 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
15931 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
15932 : SemaRef(SemaRef), CKind(CKind), Components(Components),
15933 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
15934};
15935} // namespace
15936
15937/// Return the expression of the base of the mappable expression or null if it
15938/// cannot be determined and do all the necessary checks to see if the expression
15939/// is valid as a standalone mappable expression. In the process, record all the
15940/// components of the expression.
15941static const Expr *checkMapClauseExpressionBase(
15942 Sema &SemaRef, Expr *E,
15943 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
15944 OpenMPClauseKind CKind, bool NoDiagnose) {
15945 SourceLocation ELoc = E->getExprLoc();
15946 SourceRange ERange = E->getSourceRange();
15947 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
15948 ERange);
15949 if (Checker.Visit(E->IgnoreParens()))
15950 return Checker.getFoundBase();
15951 return nullptr;
15952}
15953
15954// Return true if expression E associated with value VD has conflicts with other
15955// map information.
15956static bool checkMapConflicts(
15957 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
15958 bool CurrentRegionOnly,
15959 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
15960 OpenMPClauseKind CKind) {
15961 assert(VD && E)((VD && E) ? static_cast<void> (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15961, __PRETTY_FUNCTION__))
;
15962 SourceLocation ELoc = E->getExprLoc();
15963 SourceRange ERange = E->getSourceRange();
15964
15965 // In order to easily check the conflicts we need to match each component of
15966 // the expression under test with the components of the expressions that are
15967 // already in the stack.
15968
15969 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15969, __PRETTY_FUNCTION__))
;
15970 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15971, __PRETTY_FUNCTION__))
15971 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15971, __PRETTY_FUNCTION__))
;
15972
15973 // Variables to help detecting enclosing problems in data environment nests.
15974 bool IsEnclosedByDataEnvironmentExpr = false;
15975 const Expr *EnclosingExpr = nullptr;
15976
15977 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
15978 VD, CurrentRegionOnly,
15979 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
15980 ERange, CKind, &EnclosingExpr,
15981 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
15982 StackComponents,
15983 OpenMPClauseKind) {
15984 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15985, __PRETTY_FUNCTION__))
15985 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15985, __PRETTY_FUNCTION__))
;
15986 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15987, __PRETTY_FUNCTION__))
15987 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 15987, __PRETTY_FUNCTION__))
;
15988 (void)VD;
15989
15990 // The whole expression in the stack.
15991 const Expr *RE = StackComponents.front().getAssociatedExpression();
15992
15993 // Expressions must start from the same base. Here we detect at which
15994 // point both expressions diverge from each other and see if we can
15995 // detect if the memory referred to both expressions is contiguous and
15996 // do not overlap.
15997 auto CI = CurComponents.rbegin();
15998 auto CE = CurComponents.rend();
15999 auto SI = StackComponents.rbegin();
16000 auto SE = StackComponents.rend();
16001 for (; CI != CE && SI != SE; ++CI, ++SI) {
16002
16003 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
16004 // At most one list item can be an array item derived from a given
16005 // variable in map clauses of the same construct.
16006 if (CurrentRegionOnly &&
16007 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
16008 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
16009 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
16010 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
16011 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
16012 diag::err_omp_multiple_array_items_in_map_clause)
16013 << CI->getAssociatedExpression()->getSourceRange();
16014 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
16015 diag::note_used_here)
16016 << SI->getAssociatedExpression()->getSourceRange();
16017 return true;
16018 }
16019
16020 // Do both expressions have the same kind?
16021 if (CI->getAssociatedExpression()->getStmtClass() !=
16022 SI->getAssociatedExpression()->getStmtClass())
16023 break;
16024
16025 // Are we dealing with different variables/fields?
16026 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
16027 break;
16028 }
16029 // Check if the extra components of the expressions in the enclosing
16030 // data environment are redundant for the current base declaration.
16031 // If they are, the maps completely overlap, which is legal.
16032 for (; SI != SE; ++SI) {
16033 QualType Type;
16034 if (const auto *ASE =
16035 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
16036 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
16037 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
16038 SI->getAssociatedExpression())) {
16039 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16040 Type =
16041 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16042 }
16043 if (Type.isNull() || Type->isAnyPointerType() ||
16044 checkArrayExpressionDoesNotReferToWholeSize(
16045 SemaRef, SI->getAssociatedExpression(), Type))
16046 break;
16047 }
16048
16049 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
16050 // List items of map clauses in the same construct must not share
16051 // original storage.
16052 //
16053 // If the expressions are exactly the same or one is a subset of the
16054 // other, it means they are sharing storage.
16055 if (CI == CE && SI == SE) {
16056 if (CurrentRegionOnly) {
16057 if (CKind == OMPC_map) {
16058 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
16059 } else {
16060 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16060, __PRETTY_FUNCTION__))
;
16061 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
16062 << ERange;
16063 }
16064 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
16065 << RE->getSourceRange();
16066 return true;
16067 }
16068 // If we find the same expression in the enclosing data environment,
16069 // that is legal.
16070 IsEnclosedByDataEnvironmentExpr = true;
16071 return false;
16072 }
16073
16074 QualType DerivedType =
16075 std::prev(CI)->getAssociatedDeclaration()->getType();
16076 SourceLocation DerivedLoc =
16077 std::prev(CI)->getAssociatedExpression()->getExprLoc();
16078
16079 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16080 // If the type of a list item is a reference to a type T then the type
16081 // will be considered to be T for all purposes of this clause.
16082 DerivedType = DerivedType.getNonReferenceType();
16083
16084 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
16085 // A variable for which the type is pointer and an array section
16086 // derived from that variable must not appear as list items of map
16087 // clauses of the same construct.
16088 //
16089 // Also, cover one of the cases in:
16090 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
16091 // If any part of the original storage of a list item has corresponding
16092 // storage in the device data environment, all of the original storage
16093 // must have corresponding storage in the device data environment.
16094 //
16095 if (DerivedType->isAnyPointerType()) {
16096 if (CI == CE || SI == SE) {
16097 SemaRef.Diag(
16098 DerivedLoc,
16099 diag::err_omp_pointer_mapped_along_with_derived_section)
16100 << DerivedLoc;
16101 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
16102 << RE->getSourceRange();
16103 return true;
16104 }
16105 if (CI->getAssociatedExpression()->getStmtClass() !=
16106 SI->getAssociatedExpression()->getStmtClass() ||
16107 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
16108 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
16109 assert(CI != CE && SI != SE)((CI != CE && SI != SE) ? static_cast<void> (0)
: __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16109, __PRETTY_FUNCTION__))
;
16110 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
16111 << DerivedLoc;
16112 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
16113 << RE->getSourceRange();
16114 return true;
16115 }
16116 }
16117
16118 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
16119 // List items of map clauses in the same construct must not share
16120 // original storage.
16121 //
16122 // An expression is a subset of the other.
16123 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
16124 if (CKind == OMPC_map) {
16125 if (CI != CE || SI != SE) {
16126 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
16127 // a pointer.
16128 auto Begin =
16129 CI != CE ? CurComponents.begin() : StackComponents.begin();
16130 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
16131 auto It = Begin;
16132 while (It != End && !It->getAssociatedDeclaration())
16133 std::advance(It, 1);
16134 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16135, __PRETTY_FUNCTION__))
16135 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16135, __PRETTY_FUNCTION__))
;
16136 if (It != Begin && It->getAssociatedDeclaration()
16137 ->getType()
16138 .getCanonicalType()
16139 ->isAnyPointerType()) {
16140 IsEnclosedByDataEnvironmentExpr = false;
16141 EnclosingExpr = nullptr;
16142 return false;
16143 }
16144 }
16145 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
16146 } else {
16147 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16147, __PRETTY_FUNCTION__))
;
16148 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
16149 << ERange;
16150 }
16151 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
16152 << RE->getSourceRange();
16153 return true;
16154 }
16155
16156 // The current expression uses the same base as other expression in the
16157 // data environment but does not contain it completely.
16158 if (!CurrentRegionOnly && SI != SE)
16159 EnclosingExpr = RE;
16160
16161 // The current expression is a subset of the expression in the data
16162 // environment.
16163 IsEnclosedByDataEnvironmentExpr |=
16164 (!CurrentRegionOnly && CI != CE && SI == SE);
16165
16166 return false;
16167 });
16168
16169 if (CurrentRegionOnly)
16170 return FoundError;
16171
16172 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
16173 // If any part of the original storage of a list item has corresponding
16174 // storage in the device data environment, all of the original storage must
16175 // have corresponding storage in the device data environment.
16176 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
16177 // If a list item is an element of a structure, and a different element of
16178 // the structure has a corresponding list item in the device data environment
16179 // prior to a task encountering the construct associated with the map clause,
16180 // then the list item must also have a corresponding list item in the device
16181 // data environment prior to the task encountering the construct.
16182 //
16183 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
16184 SemaRef.Diag(ELoc,
16185 diag::err_omp_original_storage_is_shared_and_does_not_contain)
16186 << ERange;
16187 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
16188 << EnclosingExpr->getSourceRange();
16189 return true;
16190 }
16191
16192 return FoundError;
16193}
16194
16195// Look up the user-defined mapper given the mapper name and mapped type, and
16196// build a reference to it.
16197static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
16198 CXXScopeSpec &MapperIdScopeSpec,
16199 const DeclarationNameInfo &MapperId,
16200 QualType Type,
16201 Expr *UnresolvedMapper) {
16202 if (MapperIdScopeSpec.isInvalid())
16203 return ExprError();
16204 // Get the actual type for the array type.
16205 if (Type->isArrayType()) {
16206 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16206, __PRETTY_FUNCTION__))
;
16207 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
16208 }
16209 // Find all user-defined mappers with the given MapperId.
16210 SmallVector<UnresolvedSet<8>, 4> Lookups;
16211 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
16212 Lookup.suppressDiagnostics();
16213 if (S) {
16214 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
16215 NamedDecl *D = Lookup.getRepresentativeDecl();
16216 while (S && !S->isDeclScope(D))
16217 S = S->getParent();
16218 if (S)
16219 S = S->getParent();
16220 Lookups.emplace_back();
16221 Lookups.back().append(Lookup.begin(), Lookup.end());
16222 Lookup.clear();
16223 }
16224 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
16225 // Extract the user-defined mappers with the given MapperId.
16226 Lookups.push_back(UnresolvedSet<8>());
16227 for (NamedDecl *D : ULE->decls()) {
16228 auto *DMD = cast<OMPDeclareMapperDecl>(D);
16229 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16229, __PRETTY_FUNCTION__))
;
16230 Lookups.back().addDecl(DMD);
16231 }
16232 }
16233 // Defer the lookup for dependent types. The results will be passed through
16234 // UnresolvedMapper on instantiation.
16235 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
16236 Type->isInstantiationDependentType() ||
16237 Type->containsUnexpandedParameterPack() ||
16238 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16239 return !D->isInvalidDecl() &&
16240 (D->getType()->isDependentType() ||
16241 D->getType()->isInstantiationDependentType() ||
16242 D->getType()->containsUnexpandedParameterPack());
16243 })) {
16244 UnresolvedSet<8> URS;
16245 for (const UnresolvedSet<8> &Set : Lookups) {
16246 if (Set.empty())
16247 continue;
16248 URS.append(Set.begin(), Set.end());
16249 }
16250 return UnresolvedLookupExpr::Create(
16251 SemaRef.Context, /*NamingClass=*/nullptr,
16252 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
16253 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
16254 }
16255 SourceLocation Loc = MapperId.getLoc();
16256 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
16257 // The type must be of struct, union or class type in C and C++
16258 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
16259 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
16260 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
16261 return ExprError();
16262 }
16263 // Perform argument dependent lookup.
16264 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
16265 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
16266 // Return the first user-defined mapper with the desired type.
16267 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16268 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
16269 if (!D->isInvalidDecl() &&
16270 SemaRef.Context.hasSameType(D->getType(), Type))
16271 return D;
16272 return nullptr;
16273 }))
16274 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
16275 // Find the first user-defined mapper with a type derived from the desired
16276 // type.
16277 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16278 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
16279 if (!D->isInvalidDecl() &&
16280 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
16281 !Type.isMoreQualifiedThan(D->getType()))
16282 return D;
16283 return nullptr;
16284 })) {
16285 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16286 /*DetectVirtual=*/false);
16287 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
16288 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16289 VD->getType().getUnqualifiedType()))) {
16290 if (SemaRef.CheckBaseClassAccess(
16291 Loc, VD->getType(), Type, Paths.front(),
16292 /*DiagID=*/0) != Sema::AR_inaccessible) {
16293 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
16294 }
16295 }
16296 }
16297 }
16298 // Report error if a mapper is specified, but cannot be found.
16299 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
16300 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
16301 << Type << MapperId.getName();
16302 return ExprError();
16303 }
16304 return ExprEmpty();
16305}
16306
16307namespace {
16308// Utility struct that gathers all the related lists associated with a mappable
16309// expression.
16310struct MappableVarListInfo {
16311 // The list of expressions.
16312 ArrayRef<Expr *> VarList;
16313 // The list of processed expressions.
16314 SmallVector<Expr *, 16> ProcessedVarList;
16315 // The mappble components for each expression.
16316 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
16317 // The base declaration of the variable.
16318 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
16319 // The reference to the user-defined mapper associated with every expression.
16320 SmallVector<Expr *, 16> UDMapperList;
16321
16322 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
16323 // We have a list of components and base declarations for each entry in the
16324 // variable list.
16325 VarComponents.reserve(VarList.size());
16326 VarBaseDeclarations.reserve(VarList.size());
16327 }
16328};
16329}
16330
16331// Check the validity of the provided variable list for the provided clause kind
16332// \a CKind. In the check process the valid expressions, mappable expression
16333// components, variables, and user-defined mappers are extracted and used to
16334// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
16335// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
16336// and \a MapperId are expected to be valid if the clause kind is 'map'.
16337static void checkMappableExpressionList(
16338 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
16339 MappableVarListInfo &MVLI, SourceLocation StartLoc,
16340 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
16341 ArrayRef<Expr *> UnresolvedMappers,
16342 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
16343 bool IsMapTypeImplicit = false) {
16344 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
16345 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16346, __PRETTY_FUNCTION__))
16346 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16346, __PRETTY_FUNCTION__))
;
16347
16348 // If the identifier of user-defined mapper is not specified, it is "default".
16349 // We do not change the actual name in this clause to distinguish whether a
16350 // mapper is specified explicitly, i.e., it is not explicitly specified when
16351 // MapperId.getName() is empty.
16352 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
16353 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
16354 MapperId.setName(DeclNames.getIdentifier(
16355 &SemaRef.getASTContext().Idents.get("default")));
16356 }
16357
16358 // Iterators to find the current unresolved mapper expression.
16359 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
16360 bool UpdateUMIt = false;
16361 Expr *UnresolvedMapper = nullptr;
16362
16363 // Keep track of the mappable components and base declarations in this clause.
16364 // Each entry in the list is going to have a list of components associated. We
16365 // record each set of the components so that we can build the clause later on.
16366 // In the end we should have the same amount of declarations and component
16367 // lists.
16368
16369 for (Expr *RE : MVLI.VarList) {
16370 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16370, __PRETTY_FUNCTION__))
;
16371 SourceLocation ELoc = RE->getExprLoc();
16372
16373 // Find the current unresolved mapper expression.
16374 if (UpdateUMIt && UMIt != UMEnd) {
16375 UMIt++;
16376 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16378, __PRETTY_FUNCTION__))
16377 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16378, __PRETTY_FUNCTION__))
16378 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16378, __PRETTY_FUNCTION__))
;
16379 }
16380 UpdateUMIt = true;
16381 if (UMIt != UMEnd)
16382 UnresolvedMapper = *UMIt;
16383
16384 const Expr *VE = RE->IgnoreParenLValueCasts();
16385
16386 if (VE->isValueDependent() || VE->isTypeDependent() ||
16387 VE->isInstantiationDependent() ||
16388 VE->containsUnexpandedParameterPack()) {
16389 // Try to find the associated user-defined mapper.
16390 ExprResult ER = buildUserDefinedMapperRef(
16391 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
16392 VE->getType().getCanonicalType(), UnresolvedMapper);
16393 if (ER.isInvalid())
16394 continue;
16395 MVLI.UDMapperList.push_back(ER.get());
16396 // We can only analyze this information once the missing information is
16397 // resolved.
16398 MVLI.ProcessedVarList.push_back(RE);
16399 continue;
16400 }
16401
16402 Expr *SimpleExpr = RE->IgnoreParenCasts();
16403
16404 if (!RE->isLValue()) {
16405 if (SemaRef.getLangOpts().OpenMP < 50) {
16406 SemaRef.Diag(
16407 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
16408 << RE->getSourceRange();
16409 } else {
16410 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16411 << getOpenMPClauseName(CKind) << RE->getSourceRange();
16412 }
16413 continue;
16414 }
16415
16416 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
16417 ValueDecl *CurDeclaration = nullptr;
16418
16419 // Obtain the array or member expression bases if required. Also, fill the
16420 // components array with all the components identified in the process.
16421 const Expr *BE = checkMapClauseExpressionBase(
16422 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
16423 if (!BE)
16424 continue;
16425
16426 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16427, __PRETTY_FUNCTION__))
16427 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16427, __PRETTY_FUNCTION__))
;
16428
16429 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
16430 // Add store "this" pointer to class in DSAStackTy for future checking
16431 DSAS->addMappedClassesQualTypes(TE->getType());
16432 // Try to find the associated user-defined mapper.
16433 ExprResult ER = buildUserDefinedMapperRef(
16434 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
16435 VE->getType().getCanonicalType(), UnresolvedMapper);
16436 if (ER.isInvalid())
16437 continue;
16438 MVLI.UDMapperList.push_back(ER.get());
16439 // Skip restriction checking for variable or field declarations
16440 MVLI.ProcessedVarList.push_back(RE);
16441 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16442 MVLI.VarComponents.back().append(CurComponents.begin(),
16443 CurComponents.end());
16444 MVLI.VarBaseDeclarations.push_back(nullptr);
16445 continue;
16446 }
16447
16448 // For the following checks, we rely on the base declaration which is
16449 // expected to be associated with the last component. The declaration is
16450 // expected to be a variable or a field (if 'this' is being mapped).
16451 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
16452 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16452, __PRETTY_FUNCTION__))
;
16453 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16455, __PRETTY_FUNCTION__))
16454 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16455, __PRETTY_FUNCTION__))
16455 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16455, __PRETTY_FUNCTION__))
;
16456
16457 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
16458 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
16459
16460 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16460, __PRETTY_FUNCTION__))
;
16461 (void)FD;
16462
16463 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
16464 // threadprivate variables cannot appear in a map clause.
16465 // OpenMP 4.5 [2.10.5, target update Construct]
16466 // threadprivate variables cannot appear in a from clause.
16467 if (VD && DSAS->isThreadPrivate(VD)) {
16468 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
16469 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
16470 << getOpenMPClauseName(CKind);
16471 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
16472 continue;
16473 }
16474
16475 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
16476 // A list item cannot appear in both a map clause and a data-sharing
16477 // attribute clause on the same construct.
16478
16479 // Check conflicts with other map clause expressions. We check the conflicts
16480 // with the current construct separately from the enclosing data
16481 // environment, because the restrictions are different. We only have to
16482 // check conflicts across regions for the map clauses.
16483 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
16484 /*CurrentRegionOnly=*/true, CurComponents, CKind))
16485 break;
16486 if (CKind == OMPC_map &&
16487 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
16488 /*CurrentRegionOnly=*/false, CurComponents, CKind))
16489 break;
16490
16491 // OpenMP 4.5 [2.10.5, target update Construct]
16492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16493 // If the type of a list item is a reference to a type T then the type will
16494 // be considered to be T for all purposes of this clause.
16495 auto I = llvm::find_if(
16496 CurComponents,
16497 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
16498 return MC.getAssociatedDeclaration();
16499 });
16500 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16500, __PRETTY_FUNCTION__))
;
16501 QualType Type;
16502 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
16503 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
16504 if (ASE) {
16505 Type = ASE->getType().getNonReferenceType();
16506 } else if (OASE) {
16507 QualType BaseType =
16508 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16509 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16510 Type = ATy->getElementType();
16511 else
16512 Type = BaseType->getPointeeType();
16513 Type = Type.getNonReferenceType();
16514 } else {
16515 Type = VE->getType();
16516 }
16517
16518 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
16519 // A list item in a to or from clause must have a mappable type.
16520 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
16521 // A list item must have a mappable type.
16522 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
16523 DSAS, Type))
16524 continue;
16525
16526 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
16527
16528 if (CKind == OMPC_map) {
16529 // target enter data
16530 // OpenMP [2.10.2, Restrictions, p. 99]
16531 // A map-type must be specified in all map clauses and must be either
16532 // to or alloc.
16533 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
16534 if (DKind == OMPD_target_enter_data &&
16535 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
16536 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16537 << (IsMapTypeImplicit ? 1 : 0)
16538 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
16539 << getOpenMPDirectiveName(DKind);
16540 continue;
16541 }
16542
16543 // target exit_data
16544 // OpenMP [2.10.3, Restrictions, p. 102]
16545 // A map-type must be specified in all map clauses and must be either
16546 // from, release, or delete.
16547 if (DKind == OMPD_target_exit_data &&
16548 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
16549 MapType == OMPC_MAP_delete)) {
16550 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16551 << (IsMapTypeImplicit ? 1 : 0)
16552 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
16553 << getOpenMPDirectiveName(DKind);
16554 continue;
16555 }
16556
16557 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
16558 // A list item cannot appear in both a map clause and a data-sharing
16559 // attribute clause on the same construct
16560 //
16561 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
16562 // A list item cannot appear in both a map clause and a data-sharing
16563 // attribute clause on the same construct unless the construct is a
16564 // combined construct.
16565 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
16566 isOpenMPTargetExecutionDirective(DKind)) ||
16567 DKind == OMPD_target)) {
16568 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
16569 if (isOpenMPPrivate(DVar.CKind)) {
16570 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16571 << getOpenMPClauseName(DVar.CKind)
16572 << getOpenMPClauseName(OMPC_map)
16573 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
16574 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
16575 continue;
16576 }
16577 }
16578 }
16579
16580 // Try to find the associated user-defined mapper.
16581 ExprResult ER = buildUserDefinedMapperRef(
16582 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
16583 Type.getCanonicalType(), UnresolvedMapper);
16584 if (ER.isInvalid())
16585 continue;
16586 MVLI.UDMapperList.push_back(ER.get());
16587
16588 // Save the current expression.
16589 MVLI.ProcessedVarList.push_back(RE);
16590
16591 // Store the components in the stack so that they can be used to check
16592 // against other clauses later on.
16593 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
16594 /*WhereFoundClauseKind=*/OMPC_map);
16595
16596 // Save the components and declaration to create the clause. For purposes of
16597 // the clause creation, any component list that has has base 'this' uses
16598 // null as base declaration.
16599 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16600 MVLI.VarComponents.back().append(CurComponents.begin(),
16601 CurComponents.end());
16602 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
16603 : CurDeclaration);
16604 }
16605}
16606
16607OMPClause *Sema::ActOnOpenMPMapClause(
16608 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
16609 ArrayRef<SourceLocation> MapTypeModifiersLoc,
16610 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
16611 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
16612 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
16613 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
16614 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
16615 OMPC_MAP_MODIFIER_unknown,
16616 OMPC_MAP_MODIFIER_unknown};
16617 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers];
16618
16619 // Process map-type-modifiers, flag errors for duplicate modifiers.
16620 unsigned Count = 0;
16621 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
16622 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
16623 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
16624 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
16625 continue;
16626 }
16627 assert(Count < OMPMapClause::NumberOfModifiers &&((Count < OMPMapClause::NumberOfModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < OMPMapClause::NumberOfModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16628, __PRETTY_FUNCTION__))
16628 "Modifiers exceed the allowed number of map type modifiers")((Count < OMPMapClause::NumberOfModifiers && "Modifiers exceed the allowed number of map type modifiers"
) ? static_cast<void> (0) : __assert_fail ("Count < OMPMapClause::NumberOfModifiers && \"Modifiers exceed the allowed number of map type modifiers\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16628, __PRETTY_FUNCTION__))
;
16629 Modifiers[Count] = MapTypeModifiers[I];
16630 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
16631 ++Count;
16632 }
16633
16634 MappableVarListInfo MVLI(VarList);
16635 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, Locs.StartLoc,
16636 MapperIdScopeSpec, MapperId, UnresolvedMappers,
16637 MapType, IsMapTypeImplicit);
16638
16639 // We need to produce a map clause even if we don't have variables so that
16640 // other diagnostics related with non-existing map clauses are accurate.
16641 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
16642 MVLI.VarBaseDeclarations, MVLI.VarComponents,
16643 MVLI.UDMapperList, Modifiers, ModifiersLoc,
16644 MapperIdScopeSpec.getWithLocInContext(Context),
16645 MapperId, MapType, IsMapTypeImplicit, MapLoc);
16646}
16647
16648QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
16649 TypeResult ParsedType) {
16650 assert(ParsedType.isUsable())((ParsedType.isUsable()) ? static_cast<void> (0) : __assert_fail
("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16650, __PRETTY_FUNCTION__))
;
16651
16652 QualType ReductionType = GetTypeFromParser(ParsedType.get());
16653 if (ReductionType.isNull())
16654 return QualType();
16655
16656 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
16657 // A type name in a declare reduction directive cannot be a function type, an
16658 // array type, a reference type, or a type qualified with const, volatile or
16659 // restrict.
16660 if (ReductionType.hasQualifiers()) {
16661 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
16662 return QualType();
16663 }
16664
16665 if (ReductionType->isFunctionType()) {
16666 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
16667 return QualType();
16668 }
16669 if (ReductionType->isReferenceType()) {
16670 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
16671 return QualType();
16672 }
16673 if (ReductionType->isArrayType()) {
16674 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
16675 return QualType();
16676 }
16677 return ReductionType;
16678}
16679
16680Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
16681 Scope *S, DeclContext *DC, DeclarationName Name,
16682 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
16683 AccessSpecifier AS, Decl *PrevDeclInScope) {
16684 SmallVector<Decl *, 8> Decls;
16685 Decls.reserve(ReductionTypes.size());
16686
16687 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
16688 forRedeclarationInCurContext());
16689 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
16690 // A reduction-identifier may not be re-declared in the current scope for the
16691 // same type or for a type that is compatible according to the base language
16692 // rules.
16693 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16694 OMPDeclareReductionDecl *PrevDRD = nullptr;
16695 bool InCompoundScope = true;
16696 if (S != nullptr) {
16697 // Find previous declaration with the same name not referenced in other
16698 // declarations.
16699 FunctionScopeInfo *ParentFn = getEnclosingFunction();
16700 InCompoundScope =
16701 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
16702 LookupName(Lookup, S);
16703 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
16704 /*AllowInlineNamespace=*/false);
16705 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
16706 LookupResult::Filter Filter = Lookup.makeFilter();
16707 while (Filter.hasNext()) {
16708 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
16709 if (InCompoundScope) {
16710 auto I = UsedAsPrevious.find(PrevDecl);
16711 if (I == UsedAsPrevious.end())
16712 UsedAsPrevious[PrevDecl] = false;
16713 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
16714 UsedAsPrevious[D] = true;
16715 }
16716 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16717 PrevDecl->getLocation();
16718 }
16719 Filter.done();
16720 if (InCompoundScope) {
16721 for (const auto &PrevData : UsedAsPrevious) {
16722 if (!PrevData.second) {
16723 PrevDRD = PrevData.first;
16724 break;
16725 }
16726 }
16727 }
16728 } else if (PrevDeclInScope != nullptr) {
16729 auto *PrevDRDInScope = PrevDRD =
16730 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
16731 do {
16732 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
16733 PrevDRDInScope->getLocation();
16734 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
16735 } while (PrevDRDInScope != nullptr);
16736 }
16737 for (const auto &TyData : ReductionTypes) {
16738 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
16739 bool Invalid = false;
16740 if (I != PreviousRedeclTypes.end()) {
16741 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
16742 << TyData.first;
16743 Diag(I->second, diag::note_previous_definition);
16744 Invalid = true;
16745 }
16746 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
16747 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
16748 Name, TyData.first, PrevDRD);
16749 DC->addDecl(DRD);
16750 DRD->setAccess(AS);
16751 Decls.push_back(DRD);
16752 if (Invalid)
16753 DRD->setInvalidDecl();
16754 else
16755 PrevDRD = DRD;
16756 }
16757
16758 return DeclGroupPtrTy::make(
16759 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
16760}
16761
16762void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
16763 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16764
16765 // Enter new function scope.
16766 PushFunctionScope();
16767 setFunctionHasBranchProtectedScope();
16768 getCurFunction()->setHasOMPDeclareReductionCombiner();
16769
16770 if (S != nullptr)
16771 PushDeclContext(S, DRD);
16772 else
16773 CurContext = DRD;
16774
16775 PushExpressionEvaluationContext(
16776 ExpressionEvaluationContext::PotentiallyEvaluated);
16777
16778 QualType ReductionType = DRD->getType();
16779 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
16780 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
16781 // uses semantics of argument handles by value, but it should be passed by
16782 // reference. C lang does not support references, so pass all parameters as
16783 // pointers.
16784 // Create 'T omp_in;' variable.
16785 VarDecl *OmpInParm =
16786 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
16787 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
16788 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
16789 // uses semantics of argument handles by value, but it should be passed by
16790 // reference. C lang does not support references, so pass all parameters as
16791 // pointers.
16792 // Create 'T omp_out;' variable.
16793 VarDecl *OmpOutParm =
16794 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
16795 if (S != nullptr) {
16796 PushOnScopeChains(OmpInParm, S);
16797 PushOnScopeChains(OmpOutParm, S);
16798 } else {
16799 DRD->addDecl(OmpInParm);
16800 DRD->addDecl(OmpOutParm);
16801 }
16802 Expr *InE =
16803 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
16804 Expr *OutE =
16805 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
16806 DRD->setCombinerData(InE, OutE);
16807}
16808
16809void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
16810 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16811 DiscardCleanupsInEvaluationContext();
16812 PopExpressionEvaluationContext();
16813
16814 PopDeclContext();
16815 PopFunctionScopeInfo();
16816
16817 if (Combiner != nullptr)
16818 DRD->setCombiner(Combiner);
16819 else
16820 DRD->setInvalidDecl();
16821}
16822
16823VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
16824 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16825
16826 // Enter new function scope.
16827 PushFunctionScope();
16828 setFunctionHasBranchProtectedScope();
16829
16830 if (S != nullptr)
16831 PushDeclContext(S, DRD);
16832 else
16833 CurContext = DRD;
16834
16835 PushExpressionEvaluationContext(
16836 ExpressionEvaluationContext::PotentiallyEvaluated);
16837
16838 QualType ReductionType = DRD->getType();
16839 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
16840 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
16841 // uses semantics of argument handles by value, but it should be passed by
16842 // reference. C lang does not support references, so pass all parameters as
16843 // pointers.
16844 // Create 'T omp_priv;' variable.
16845 VarDecl *OmpPrivParm =
16846 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
16847 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
16848 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
16849 // uses semantics of argument handles by value, but it should be passed by
16850 // reference. C lang does not support references, so pass all parameters as
16851 // pointers.
16852 // Create 'T omp_orig;' variable.
16853 VarDecl *OmpOrigParm =
16854 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
16855 if (S != nullptr) {
16856 PushOnScopeChains(OmpPrivParm, S);
16857 PushOnScopeChains(OmpOrigParm, S);
16858 } else {
16859 DRD->addDecl(OmpPrivParm);
16860 DRD->addDecl(OmpOrigParm);
16861 }
16862 Expr *OrigE =
16863 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
16864 Expr *PrivE =
16865 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
16866 DRD->setInitializerData(OrigE, PrivE);
16867 return OmpPrivParm;
16868}
16869
16870void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
16871 VarDecl *OmpPrivParm) {
16872 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16873 DiscardCleanupsInEvaluationContext();
16874 PopExpressionEvaluationContext();
16875
16876 PopDeclContext();
16877 PopFunctionScopeInfo();
16878
16879 if (Initializer != nullptr) {
16880 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
16881 } else if (OmpPrivParm->hasInit()) {
16882 DRD->setInitializer(OmpPrivParm->getInit(),
16883 OmpPrivParm->isDirectInit()
16884 ? OMPDeclareReductionDecl::DirectInit
16885 : OMPDeclareReductionDecl::CopyInit);
16886 } else {
16887 DRD->setInvalidDecl();
16888 }
16889}
16890
16891Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
16892 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
16893 for (Decl *D : DeclReductions.get()) {
16894 if (IsValid) {
16895 if (S)
16896 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
16897 /*AddToContext=*/false);
16898 } else {
16899 D->setInvalidDecl();
16900 }
16901 }
16902 return DeclReductions;
16903}
16904
16905TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
16906 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
16907 QualType T = TInfo->getType();
16908 if (D.isInvalidType())
16909 return true;
16910
16911 if (getLangOpts().CPlusPlus) {
16912 // Check that there are no default arguments (C++ only).
16913 CheckExtraCXXDefaultArguments(D);
16914 }
16915
16916 return CreateParsedType(T, TInfo);
16917}
16918
16919QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
16920 TypeResult ParsedType) {
16921 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16921, __PRETTY_FUNCTION__))
;
16922
16923 QualType MapperType = GetTypeFromParser(ParsedType.get());
16924 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 16924, __PRETTY_FUNCTION__))
;
16925
16926 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
16927 // The type must be of struct, union or class type in C and C++
16928 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
16929 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
16930 return QualType();
16931 }
16932 return MapperType;
16933}
16934
16935OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
16936 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
16937 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
16938 Decl *PrevDeclInScope) {
16939 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
16940 forRedeclarationInCurContext());
16941 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
16942 // A mapper-identifier may not be redeclared in the current scope for the
16943 // same type or for a type that is compatible according to the base language
16944 // rules.
16945 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16946 OMPDeclareMapperDecl *PrevDMD = nullptr;
16947 bool InCompoundScope = true;
16948 if (S != nullptr) {
16949 // Find previous declaration with the same name not referenced in other
16950 // declarations.
16951 FunctionScopeInfo *ParentFn = getEnclosingFunction();
16952 InCompoundScope =
16953 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
16954 LookupName(Lookup, S);
16955 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
16956 /*AllowInlineNamespace=*/false);
16957 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
16958 LookupResult::Filter Filter = Lookup.makeFilter();
16959 while (Filter.hasNext()) {
16960 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
16961 if (InCompoundScope) {
16962 auto I = UsedAsPrevious.find(PrevDecl);
16963 if (I == UsedAsPrevious.end())
16964 UsedAsPrevious[PrevDecl] = false;
16965 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
16966 UsedAsPrevious[D] = true;
16967 }
16968 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16969 PrevDecl->getLocation();
16970 }
16971 Filter.done();
16972 if (InCompoundScope) {
16973 for (const auto &PrevData : UsedAsPrevious) {
16974 if (!PrevData.second) {
16975 PrevDMD = PrevData.first;
16976 break;
16977 }
16978 }
16979 }
16980 } else if (PrevDeclInScope) {
16981 auto *PrevDMDInScope = PrevDMD =
16982 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
16983 do {
16984 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
16985 PrevDMDInScope->getLocation();
16986 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
16987 } while (PrevDMDInScope != nullptr);
16988 }
16989 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
16990 bool Invalid = false;
16991 if (I != PreviousRedeclTypes.end()) {
16992 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
16993 << MapperType << Name;
16994 Diag(I->second, diag::note_previous_definition);
16995 Invalid = true;
16996 }
16997 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
16998 MapperType, VN, PrevDMD);
16999 DC->addDecl(DMD);
17000 DMD->setAccess(AS);
17001 if (Invalid)
17002 DMD->setInvalidDecl();
17003
17004 // Enter new function scope.
17005 PushFunctionScope();
17006 setFunctionHasBranchProtectedScope();
17007
17008 CurContext = DMD;
17009
17010 return DMD;
17011}
17012
17013void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
17014 Scope *S,
17015 QualType MapperType,
17016 SourceLocation StartLoc,
17017 DeclarationName VN) {
17018 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
17019 if (S)
17020 PushOnScopeChains(VD, S);
17021 else
17022 DMD->addDecl(VD);
17023 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
17024 DMD->setMapperVarRef(MapperVarRefExpr);
17025}
17026
17027Sema::DeclGroupPtrTy
17028Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
17029 ArrayRef<OMPClause *> ClauseList) {
17030 PopDeclContext();
17031 PopFunctionScopeInfo();
17032
17033 if (D) {
17034 if (S)
17035 PushOnScopeChains(D, S, /*AddToContext=*/false);
17036 D->CreateClauses(Context, ClauseList);
17037 }
17038
17039 return DeclGroupPtrTy::make(DeclGroupRef(D));
17040}
17041
17042OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
17043 SourceLocation StartLoc,
17044 SourceLocation LParenLoc,
17045 SourceLocation EndLoc) {
17046 Expr *ValExpr = NumTeams;
17047 Stmt *HelperValStmt = nullptr;
17048
17049 // OpenMP [teams Constrcut, Restrictions]
17050 // The num_teams expression must evaluate to a positive integer value.
17051 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
17052 /*StrictlyPositive=*/true))
17053 return nullptr;
17054
17055 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17056 OpenMPDirectiveKind CaptureRegion =
17057 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
17058 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17059 ValExpr = MakeFullExpr(ValExpr).get();
17060 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17061 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17062 HelperValStmt = buildPreInits(Context, Captures);
17063 }
17064
17065 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
17066 StartLoc, LParenLoc, EndLoc);
17067}
17068
17069OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
17070 SourceLocation StartLoc,
17071 SourceLocation LParenLoc,
17072 SourceLocation EndLoc) {
17073 Expr *ValExpr = ThreadLimit;
17074 Stmt *HelperValStmt = nullptr;
17075
17076 // OpenMP [teams Constrcut, Restrictions]
17077 // The thread_limit expression must evaluate to a positive integer value.
17078 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
17079 /*StrictlyPositive=*/true))
17080 return nullptr;
17081
17082 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
17083 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
17084 DKind, OMPC_thread_limit, LangOpts.OpenMP);
17085 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17086 ValExpr = MakeFullExpr(ValExpr).get();
17087 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17088 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17089 HelperValStmt = buildPreInits(Context, Captures);
17090 }
17091
17092 return new (Context) OMPThreadLimitClause(
17093 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17094}
17095
17096OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
17097 SourceLocation StartLoc,
17098 SourceLocation LParenLoc,
17099 SourceLocation EndLoc) {
17100 Expr *ValExpr = Priority;
17101 Stmt *HelperValStmt = nullptr;
17102 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17103
17104 // OpenMP [2.9.1, task Constrcut]
17105 // The priority-value is a non-negative numerical scalar expression.
17106 if (!isNonNegativeIntegerValue(
17107 ValExpr, *this, OMPC_priority,
17108 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
17109 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
17110 return nullptr;
17111
17112 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
17113 StartLoc, LParenLoc, EndLoc);
17114}
17115
17116OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
17117 SourceLocation StartLoc,
17118 SourceLocation LParenLoc,
17119 SourceLocation EndLoc) {
17120 Expr *ValExpr = Grainsize;
17121 Stmt *HelperValStmt = nullptr;
17122 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17123
17124 // OpenMP [2.9.2, taskloop Constrcut]
17125 // The parameter of the grainsize clause must be a positive integer
17126 // expression.
17127 if (!isNonNegativeIntegerValue(
17128 ValExpr, *this, OMPC_grainsize,
17129 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
17130 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
17131 return nullptr;
17132
17133 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
17134 StartLoc, LParenLoc, EndLoc);
17135}
17136
17137OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
17138 SourceLocation StartLoc,
17139 SourceLocation LParenLoc,
17140 SourceLocation EndLoc) {
17141 Expr *ValExpr = NumTasks;
17142 Stmt *HelperValStmt = nullptr;
17143 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17144
17145 // OpenMP [2.9.2, taskloop Constrcut]
17146 // The parameter of the num_tasks clause must be a positive integer
17147 // expression.
17148 if (!isNonNegativeIntegerValue(
17149 ValExpr, *this, OMPC_num_tasks,
17150 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
17151 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
17152 return nullptr;
17153
17154 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
17155 StartLoc, LParenLoc, EndLoc);
17156}
17157
17158OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
17159 SourceLocation LParenLoc,
17160 SourceLocation EndLoc) {
17161 // OpenMP [2.13.2, critical construct, Description]
17162 // ... where hint-expression is an integer constant expression that evaluates
17163 // to a valid lock hint.
17164 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
17165 if (HintExpr.isInvalid())
17166 return nullptr;
17167 return new (Context)
17168 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
17169}
17170
17171OMPClause *Sema::ActOnOpenMPDistScheduleClause(
17172 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17173 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
17174 SourceLocation EndLoc) {
17175 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
17176 std::string Values;
17177 Values += "'";
17178 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
17179 Values += "'";
17180 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17181 << Values << getOpenMPClauseName(OMPC_dist_schedule);
17182 return nullptr;
17183 }
17184 Expr *ValExpr = ChunkSize;
17185 Stmt *HelperValStmt = nullptr;
17186 if (ChunkSize) {
17187 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17188 !ChunkSize->isInstantiationDependent() &&
17189 !ChunkSize->containsUnexpandedParameterPack()) {
17190 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17191 ExprResult Val =
17192 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17193 if (Val.isInvalid())
17194 return nullptr;
17195
17196 ValExpr = Val.get();
17197
17198 // OpenMP [2.7.1, Restrictions]
17199 // chunk_size must be a loop invariant integer expression with a positive
17200 // value.
17201 llvm::APSInt Result;
17202 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
17203 if (Result.isSigned() && !Result.isStrictlyPositive()) {
17204 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17205 << "dist_schedule" << ChunkSize->getSourceRange();
17206 return nullptr;
17207 }
17208 } else if (getOpenMPCaptureRegionForClause(
17209 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule,
17210 LangOpts.OpenMP) != OMPD_unknown &&
17211 !CurContext->isDependentContext()) {
17212 ValExpr = MakeFullExpr(ValExpr).get();
17213 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17214 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17215 HelperValStmt = buildPreInits(Context, Captures);
17216 }
17217 }
17218 }
17219
17220 return new (Context)
17221 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
17222 Kind, ValExpr, HelperValStmt);
17223}
17224
17225OMPClause *Sema::ActOnOpenMPDefaultmapClause(
17226 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
17227 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
17228 SourceLocation KindLoc, SourceLocation EndLoc) {
17229 if (getLangOpts().OpenMP < 50) {
17230 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
17231 Kind != OMPC_DEFAULTMAP_scalar) {
17232 std::string Value;
17233 SourceLocation Loc;
17234 Value += "'";
17235 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
17236 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
17237 OMPC_DEFAULTMAP_MODIFIER_tofrom);
17238 Loc = MLoc;
17239 } else {
17240 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
17241 OMPC_DEFAULTMAP_scalar);
17242 Loc = KindLoc;
17243 }
17244 Value += "'";
17245 Diag(Loc, diag::err_omp_unexpected_clause_value)
17246 << Value << getOpenMPClauseName(OMPC_defaultmap);
17247 return nullptr;
17248 }
17249 } else {
17250 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
17251 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown);
17252 if (!isDefaultmapKind || !isDefaultmapModifier) {
17253 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
17254 "'firstprivate', 'none', 'default'";
17255 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
17256 if (!isDefaultmapKind && isDefaultmapModifier) {
17257 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17258 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
17259 } else if (isDefaultmapKind && !isDefaultmapModifier) {
17260 Diag(MLoc, diag::err_omp_unexpected_clause_value)
17261 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
17262 } else {
17263 Diag(MLoc, diag::err_omp_unexpected_clause_value)
17264 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
17265 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17266 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
17267 }
17268 return nullptr;
17269 }
17270
17271 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
17272 // At most one defaultmap clause for each category can appear on the
17273 // directive.
17274 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkDefaultmapCategory(Kind)) {
17275 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
17276 return nullptr;
17277 }
17278 }
17279 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAAttr(M, Kind, StartLoc);
17280
17281 return new (Context)
17282 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
17283}
17284
17285bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
17286 DeclContext *CurLexicalContext = getCurLexicalContext();
17287 if (!CurLexicalContext->isFileContext() &&
17288 !CurLexicalContext->isExternCContext() &&
17289 !CurLexicalContext->isExternCXXContext() &&
17290 !isa<CXXRecordDecl>(CurLexicalContext) &&
17291 !isa<ClassTemplateDecl>(CurLexicalContext) &&
17292 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
17293 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
17294 Diag(Loc, diag::err_omp_region_not_file_context);
17295 return false;
17296 }
17297 ++DeclareTargetNestingLevel;
17298 return true;
17299}
17300
17301void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
17302 assert(DeclareTargetNestingLevel > 0 &&((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17303, __PRETTY_FUNCTION__))
17303 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")((DeclareTargetNestingLevel > 0 && "Unexpected ActOnFinishOpenMPDeclareTargetDirective"
) ? static_cast<void> (0) : __assert_fail ("DeclareTargetNestingLevel > 0 && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17303, __PRETTY_FUNCTION__))
;
17304 --DeclareTargetNestingLevel;
17305}
17306
17307NamedDecl *
17308Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
17309 const DeclarationNameInfo &Id,
17310 NamedDeclSetType &SameDirectiveDecls) {
17311 LookupResult Lookup(*this, Id, LookupOrdinaryName);
17312 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
17313
17314 if (Lookup.isAmbiguous())
17315 return nullptr;
17316 Lookup.suppressDiagnostics();
17317
17318 if (!Lookup.isSingleResult()) {
17319 VarOrFuncDeclFilterCCC CCC(*this);
17320 if (TypoCorrection Corrected =
17321 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
17322 CTK_ErrorRecovery)) {
17323 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
17324 << Id.getName());
17325 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
17326 return nullptr;
17327 }
17328
17329 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
17330 return nullptr;
17331 }
17332
17333 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
17334 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
17335 !isa<FunctionTemplateDecl>(ND)) {
17336 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
17337 return nullptr;
17338 }
17339 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
17340 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
17341 return ND;
17342}
17343
17344void Sema::ActOnOpenMPDeclareTargetName(
17345 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
17346 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
17347 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17349, __PRETTY_FUNCTION__))
17348 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17349, __PRETTY_FUNCTION__))
17349 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17349, __PRETTY_FUNCTION__))
;
17350
17351 // Diagnose marking after use as it may lead to incorrect diagnosis and
17352 // codegen.
17353 if (LangOpts.OpenMP >= 50 &&
17354 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
17355 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
17356
17357 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
17358 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
17359 if (DevTy.hasValue() && *DevTy != DT) {
17360 Diag(Loc, diag::err_omp_device_type_mismatch)
17361 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
17362 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
17363 return;
17364 }
17365 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
17366 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
17367 if (!Res) {
17368 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
17369 SourceRange(Loc, Loc));
17370 ND->addAttr(A);
17371 if (ASTMutationListener *ML = Context.getASTMutationListener())
17372 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
17373 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
17374 } else if (*Res != MT) {
17375 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
17376 }
17377}
17378
17379static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
17380 Sema &SemaRef, Decl *D) {
17381 if (!D || !isa<VarDecl>(D))
17382 return;
17383 auto *VD = cast<VarDecl>(D);
17384 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
17385 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
17386 if (SemaRef.LangOpts.OpenMP >= 50 &&
17387 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
17388 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
17389 VD->hasGlobalStorage()) {
17390 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
17391 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
17392 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
17393 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
17394 // If a lambda declaration and definition appears between a
17395 // declare target directive and the matching end declare target
17396 // directive, all variables that are captured by the lambda
17397 // expression must also appear in a to clause.
17398 SemaRef.Diag(VD->getLocation(),
17399 diag::err_omp_lambda_capture_in_declare_target_not_to);
17400 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
17401 << VD << 0 << SR;
17402 return;
17403 }
17404 }
17405 if (MapTy.hasValue())
17406 return;
17407 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
17408 SemaRef.Diag(SL, diag::note_used_here) << SR;
17409}
17410
17411static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
17412 Sema &SemaRef, DSAStackTy *Stack,
17413 ValueDecl *VD) {
17414 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
17415 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
17416 /*FullCheck=*/false);
17417}
17418
17419void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
17420 SourceLocation IdLoc) {
17421 if (!D || D->isInvalidDecl())
17422 return;
17423 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
17424 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
17425 if (auto *VD = dyn_cast<VarDecl>(D)) {
17426 // Only global variables can be marked as declare target.
17427 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
17428 !VD->isStaticDataMember())
17429 return;
17430 // 2.10.6: threadprivate variable cannot appear in a declare target
17431 // directive.
17432 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
17433 Diag(SL, diag::err_omp_threadprivate_in_target);
17434 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
17435 return;
17436 }
17437 }
17438 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
17439 D = FTD->getTemplatedDecl();
17440 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
17441 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
17442 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
17443 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
17444 Diag(IdLoc, diag::err_omp_function_in_link_clause);
17445 Diag(FD->getLocation(), diag::note_defined_here) << FD;
17446 return;
17447 }
17448 // Mark the function as must be emitted for the device.
17449 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
17450 OMPDeclareTargetDeclAttr::getDeviceType(FD);
17451 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
17452 *DevTy != OMPDeclareTargetDeclAttr::DT_Host)
17453 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false);
17454 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
17455 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost)
17456 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false);
17457 }
17458 if (auto *VD = dyn_cast<ValueDecl>(D)) {
17459 // Problem if any with var declared with incomplete type will be reported
17460 // as normal, so no need to check it here.
17461 if ((E || !VD->getType()->isIncompleteType()) &&
17462 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD))
17463 return;
17464 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
17465 // Checking declaration inside declare target region.
17466 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
17467 isa<FunctionTemplateDecl>(D)) {
17468 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
17469 Context, OMPDeclareTargetDeclAttr::MT_To,
17470 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
17471 D->addAttr(A);
17472 if (ASTMutationListener *ML = Context.getASTMutationListener())
17473 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
17474 }
17475 return;
17476 }
17477 }
17478 if (!E)
17479 return;
17480 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
17481}
17482
17483OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
17484 CXXScopeSpec &MapperIdScopeSpec,
17485 DeclarationNameInfo &MapperId,
17486 const OMPVarListLocTy &Locs,
17487 ArrayRef<Expr *> UnresolvedMappers) {
17488 MappableVarListInfo MVLI(VarList);
17489 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, Locs.StartLoc,
17490 MapperIdScopeSpec, MapperId, UnresolvedMappers);
17491 if (MVLI.ProcessedVarList.empty())
17492 return nullptr;
17493
17494 return OMPToClause::Create(
17495 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17496 MVLI.VarComponents, MVLI.UDMapperList,
17497 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
17498}
17499
17500OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
17501 CXXScopeSpec &MapperIdScopeSpec,
17502 DeclarationNameInfo &MapperId,
17503 const OMPVarListLocTy &Locs,
17504 ArrayRef<Expr *> UnresolvedMappers) {
17505 MappableVarListInfo MVLI(VarList);
17506 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, Locs.StartLoc,
17507 MapperIdScopeSpec, MapperId, UnresolvedMappers);
17508 if (MVLI.ProcessedVarList.empty())
17509 return nullptr;
17510
17511 return OMPFromClause::Create(
17512 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17513 MVLI.VarComponents, MVLI.UDMapperList,
17514 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
17515}
17516
17517OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
17518 const OMPVarListLocTy &Locs) {
17519 MappableVarListInfo MVLI(VarList);
17520 SmallVector<Expr *, 8> PrivateCopies;
17521 SmallVector<Expr *, 8> Inits;
17522
17523 for (Expr *RefExpr : VarList) {
17524 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17524, __PRETTY_FUNCTION__))
;
17525 SourceLocation ELoc;
17526 SourceRange ERange;
17527 Expr *SimpleRefExpr = RefExpr;
17528 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17529 if (Res.second) {
17530 // It will be analyzed later.
17531 MVLI.ProcessedVarList.push_back(RefExpr);
17532 PrivateCopies.push_back(nullptr);
17533 Inits.push_back(nullptr);
17534 }
17535 ValueDecl *D = Res.first;
17536 if (!D)
17537 continue;
17538
17539 QualType Type = D->getType();
17540 Type = Type.getNonReferenceType().getUnqualifiedType();
17541
17542 auto *VD = dyn_cast<VarDecl>(D);
17543
17544 // Item should be a pointer or reference to pointer.
17545 if (!Type->isPointerType()) {
17546 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
17547 << 0 << RefExpr->getSourceRange();
17548 continue;
17549 }
17550
17551 // Build the private variable and the expression that refers to it.
17552 auto VDPrivate =
17553 buildVarDecl(*this, ELoc, Type, D->getName(),
17554 D->hasAttrs() ? &D->getAttrs() : nullptr,
17555 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17556 if (VDPrivate->isInvalidDecl())
17557 continue;
17558
17559 CurContext->addDecl(VDPrivate);
17560 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17561 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17562
17563 // Add temporary variable to initialize the private copy of the pointer.
17564 VarDecl *VDInit =
17565 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
17566 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
17567 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
17568 AddInitializerToDecl(VDPrivate,
17569 DefaultLvalueConversion(VDInitRefExpr).get(),
17570 /*DirectInit=*/false);
17571
17572 // If required, build a capture to implement the privatization initialized
17573 // with the current list item value.
17574 DeclRefExpr *Ref = nullptr;
17575 if (!VD)
17576 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17577 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
17578 PrivateCopies.push_back(VDPrivateRefExpr);
17579 Inits.push_back(VDInitRefExpr);
17580
17581 // We need to add a data sharing attribute for this variable to make sure it
17582 // is correctly captured. A variable that shows up in a use_device_ptr has
17583 // similar properties of a first private variable.
17584 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17585
17586 // Create a mappable component for the list item. List items in this clause
17587 // only need a component.
17588 MVLI.VarBaseDeclarations.push_back(D);
17589 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17590 MVLI.VarComponents.back().push_back(
17591 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
17592 }
17593
17594 if (MVLI.ProcessedVarList.empty())
17595 return nullptr;
17596
17597 return OMPUseDevicePtrClause::Create(
17598 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
17599 MVLI.VarBaseDeclarations, MVLI.VarComponents);
17600}
17601
17602OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
17603 const OMPVarListLocTy &Locs) {
17604 MappableVarListInfo MVLI(VarList);
17605 for (Expr *RefExpr : VarList) {
17606 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17606, __PRETTY_FUNCTION__))
;
17607 SourceLocation ELoc;
17608 SourceRange ERange;
17609 Expr *SimpleRefExpr = RefExpr;
17610 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17611 if (Res.second) {
17612 // It will be analyzed later.
17613 MVLI.ProcessedVarList.push_back(RefExpr);
17614 }
17615 ValueDecl *D = Res.first;
17616 if (!D)
17617 continue;
17618
17619 QualType Type = D->getType();
17620 // item should be a pointer or array or reference to pointer or array
17621 if (!Type.getNonReferenceType()->isPointerType() &&
17622 !Type.getNonReferenceType()->isArrayType()) {
17623 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
17624 << 0 << RefExpr->getSourceRange();
17625 continue;
17626 }
17627
17628 // Check if the declaration in the clause does not show up in any data
17629 // sharing attribute.
17630 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, /*FromParent=*/false);
17631 if (isOpenMPPrivate(DVar.CKind)) {
17632 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17633 << getOpenMPClauseName(DVar.CKind)
17634 << getOpenMPClauseName(OMPC_is_device_ptr)
17635 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
17636 reportOriginalDsa(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
17637 continue;
17638 }
17639
17640 const Expr *ConflictExpr;
17641 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
17642 D, /*CurrentRegionOnly=*/true,
17643 [&ConflictExpr](
17644 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
17645 OpenMPClauseKind) -> bool {
17646 ConflictExpr = R.front().getAssociatedExpression();
17647 return true;
17648 })) {
17649 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
17650 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
17651 << ConflictExpr->getSourceRange();
17652 continue;
17653 }
17654
17655 // Store the components in the stack so that they can be used to check
17656 // against other clauses later on.
17657 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
17658 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
17659 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
17660
17661 // Record the expression we've just processed.
17662 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
17663
17664 // Create a mappable component for the list item. List items in this clause
17665 // only need a component. We use a null declaration to signal fields in
17666 // 'this'.
17667 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17669, __PRETTY_FUNCTION__))
17668 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17669, __PRETTY_FUNCTION__))
17669 "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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17669, __PRETTY_FUNCTION__))
;
17670 MVLI.VarBaseDeclarations.push_back(
17671 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
17672 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17673 MVLI.VarComponents.back().push_back(MC);
17674 }
17675
17676 if (MVLI.ProcessedVarList.empty())
17677 return nullptr;
17678
17679 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
17680 MVLI.VarBaseDeclarations,
17681 MVLI.VarComponents);
17682}
17683
17684OMPClause *Sema::ActOnOpenMPAllocateClause(
17685 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
17686 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
17687 if (Allocator) {
17688 // OpenMP [2.11.4 allocate Clause, Description]
17689 // allocator is an expression of omp_allocator_handle_t type.
17690 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
17691 return nullptr;
17692
17693 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
17694 if (AllocatorRes.isInvalid())
17695 return nullptr;
17696 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
17697 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getOMPAllocatorHandleT(),
17698 Sema::AA_Initializing,
17699 /*AllowExplicit=*/true);
17700 if (AllocatorRes.isInvalid())
17701 return nullptr;
17702 Allocator = AllocatorRes.get();
17703 } else {
17704 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
17705 // allocate clauses that appear on a target construct or on constructs in a
17706 // target region must specify an allocator expression unless a requires
17707 // directive with the dynamic_allocators clause is present in the same
17708 // compilation unit.
17709 if (LangOpts.OpenMPIsDevice &&
17710 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
17711 targetDiag(StartLoc, diag::err_expected_allocator_expression);
17712 }
17713 // Analyze and build list of variables.
17714 SmallVector<Expr *, 8> Vars;
17715 for (Expr *RefExpr : VarList) {
17716 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17716, __PRETTY_FUNCTION__))
;
17717 SourceLocation ELoc;
17718 SourceRange ERange;
17719 Expr *SimpleRefExpr = RefExpr;
17720 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17721 if (Res.second) {
17722 // It will be analyzed later.
17723 Vars.push_back(RefExpr);
17724 }
17725 ValueDecl *D = Res.first;
17726 if (!D)
17727 continue;
17728
17729 auto *VD = dyn_cast<VarDecl>(D);
17730 DeclRefExpr *Ref = nullptr;
17731 if (!VD && !CurContext->isDependentContext())
17732 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17733 Vars.push_back((VD || CurContext->isDependentContext())
17734 ? RefExpr->IgnoreParens()
17735 : Ref);
17736 }
17737
17738 if (Vars.empty())
17739 return nullptr;
17740
17741 if (Allocator)
17742 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addInnerAllocatorExpr(Allocator);
17743 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
17744 ColonLoc, EndLoc, Vars);
17745}
17746
17747OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
17748 SourceLocation StartLoc,
17749 SourceLocation LParenLoc,
17750 SourceLocation EndLoc) {
17751 SmallVector<Expr *, 8> Vars;
17752 for (Expr *RefExpr : VarList) {
17753 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-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaOpenMP.cpp"
, 17753, __PRETTY_FUNCTION__))
;
17754 SourceLocation ELoc;
17755 SourceRange ERange;
17756 Expr *SimpleRefExpr = RefExpr;
17757 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17758 if (Res.second)
17759 // It will be analyzed later.
17760 Vars.push_back(RefExpr);
17761 ValueDecl *D = Res.first;
17762 if (!D)
17763 continue;
17764
17765 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
17766 // A list-item cannot appear in more than one nontemporal clause.
17767 if (const Expr *PrevRef =
17768 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueNontemporal(D, SimpleRefExpr)) {
17769 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17770 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
17771 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17772 << getOpenMPClauseName(OMPC_nontemporal);
17773 continue;
17774 }
17775
17776 Vars.push_back(RefExpr);
17777 }
17778
17779 if (Vars.empty())
17780 return nullptr;
17781
17782 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17783 Vars);
17784}

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h

1//===- Optional.h - Simple variant for passing optional values --*- C++ -*-===//
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//
9// This file provides Optional, a template class modeled in the spirit of
10// OCaml's 'opt' variant. The idea is to strongly type whether or not
11// a value can be optional.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_OPTIONAL_H
16#define LLVM_ADT_OPTIONAL_H
17
18#include "llvm/ADT/None.h"
19#include "llvm/Support/Compiler.h"
20#include "llvm/Support/type_traits.h"
21#include <cassert>
22#include <memory>
23#include <new>
24#include <utility>
25
26namespace llvm {
27
28class raw_ostream;
29
30namespace optional_detail {
31
32struct in_place_t {};
33
34/// Storage for any type.
35template <typename T, bool = is_trivially_copyable<T>::value>
36class OptionalStorage {
37 union {
38 char empty;
39 T value;
40 };
41 bool hasVal;
42
43public:
44 ~OptionalStorage() { reset(); }
45
46 OptionalStorage() noexcept : empty(), hasVal(false) {}
47
48 OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
49 if (other.hasValue()) {
50 emplace(other.value);
51 }
52 }
53 OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
54 if (other.hasValue()) {
55 emplace(std::move(other.value));
56 }
57 }
58
59 template <class... Args>
60 explicit OptionalStorage(in_place_t, Args &&... args)
61 : value(std::forward<Args>(args)...), hasVal(true) {}
62
63 void reset() noexcept {
64 if (hasVal) {
65 value.~T();
66 hasVal = false;
67 }
68 }
69
70 bool hasValue() const noexcept { return hasVal; }
71
72 T &getValue() LLVM_LVALUE_FUNCTION& noexcept {
73 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 73, __PRETTY_FUNCTION__))
;
74 return value;
75 }
76 T const &getValue() const LLVM_LVALUE_FUNCTION& noexcept {
77 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 77, __PRETTY_FUNCTION__))
;
78 return value;
79 }
80#if LLVM_HAS_RVALUE_REFERENCE_THIS1
81 T &&getValue() && noexcept {
82 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 82, __PRETTY_FUNCTION__))
;
83 return std::move(value);
84 }
85#endif
86
87 template <class... Args> void emplace(Args &&... args) {
88 reset();
89 ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
90 hasVal = true;
91 }
92
93 OptionalStorage &operator=(T const &y) {
94 if (hasValue()) {
95 value = y;
96 } else {
97 ::new ((void *)std::addressof(value)) T(y);
98 hasVal = true;
99 }
100 return *this;
101 }
102 OptionalStorage &operator=(T &&y) {
103 if (hasValue()) {
104 value = std::move(y);
105 } else {
106 ::new ((void *)std::addressof(value)) T(std::move(y));
107 hasVal = true;
108 }
109 return *this;
110 }
111
112 OptionalStorage &operator=(OptionalStorage const &other) {
113 if (other.hasValue()) {
114 if (hasValue()) {
115 value = other.value;
116 } else {
117 ::new ((void *)std::addressof(value)) T(other.value);
118 hasVal = true;
119 }
120 } else {
121 reset();
122 }
123 return *this;
124 }
125
126 OptionalStorage &operator=(OptionalStorage &&other) {
127 if (other.hasValue()) {
128 if (hasValue()) {
129 value = std::move(other.value);
130 } else {
131 ::new ((void *)std::addressof(value)) T(std::move(other.value));
132 hasVal = true;
133 }
134 } else {
135 reset();
136 }
137 return *this;
138 }
139};
140
141template <typename T> class OptionalStorage<T, true> {
142 union {
143 char empty;
144 T value;
145 };
146 bool hasVal = false;
147
148public:
149 ~OptionalStorage() = default;
150
151 OptionalStorage() noexcept : empty{} {}
152
153 OptionalStorage(OptionalStorage const &other) = default;
154 OptionalStorage(OptionalStorage &&other) = default;
155
156 OptionalStorage &operator=(OptionalStorage const &other) = default;
157 OptionalStorage &operator=(OptionalStorage &&other) = default;
158
159 template <class... Args>
160 explicit OptionalStorage(in_place_t, Args &&... args)
161 : value(std::forward<Args>(args)...), hasVal(true) {}
162
163 void reset() noexcept {
164 if (hasVal) {
165 value.~T();
166 hasVal = false;
167 }
168 }
169
170 bool hasValue() const noexcept { return hasVal; }
25
Returning zero, which participates in a condition later
34
Returning zero, which participates in a condition later
171
172 T &getValue() LLVM_LVALUE_FUNCTION& noexcept {
173 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 173, __PRETTY_FUNCTION__))
;
174 return value;
175 }
176 T const &getValue() const LLVM_LVALUE_FUNCTION& noexcept {
177 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 177, __PRETTY_FUNCTION__))
;
178 return value;
179 }
180#if LLVM_HAS_RVALUE_REFERENCE_THIS1
181 T &&getValue() && noexcept {
182 assert(hasVal)((hasVal) ? static_cast<void> (0) : __assert_fail ("hasVal"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/ADT/Optional.h"
, 182, __PRETTY_FUNCTION__))
;
183 return std::move(value);
184 }
185#endif
186
187 template <class... Args> void emplace(Args &&... args) {
188 reset();
189 ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
190 hasVal = true;
191 }
192
193 OptionalStorage &operator=(T const &y) {
194 if (hasValue()) {
195 value = y;
196 } else {
197 ::new ((void *)std::addressof(value)) T(y);
198 hasVal = true;
199 }
200 return *this;
201 }
202 OptionalStorage &operator=(T &&y) {
203 if (hasValue()) {
204 value = std::move(y);
205 } else {
206 ::new ((void *)std::addressof(value)) T(std::move(y));
207 hasVal = true;
208 }
209 return *this;
210 }
211};
212
213} // namespace optional_detail
214
215template <typename T> class Optional {
216 optional_detail::OptionalStorage<T> Storage;
217
218public:
219 using value_type = T;
220
221 constexpr Optional() {}
222 constexpr Optional(NoneType) {}
223
224 Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
225 Optional(const Optional &O) = default;
226
227 Optional(T &&y) : Storage(optional_detail::in_place_t{}, std::move(y)) {}
228 Optional(Optional &&O) = default;
229
230 Optional &operator=(T &&y) {
231 Storage = std::move(y);
232 return *this;
233 }
234 Optional &operator=(Optional &&O) = default;
235
236 /// Create a new object by constructing it in place with the given arguments.
237 template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
238 Storage.emplace(std::forward<ArgTypes>(Args)...);
239 }
240
241 static inline Optional create(const T *y) {
242 return y ? Optional(*y) : Optional();
243 }
244
245 Optional &operator=(const T &y) {
246 Storage = y;
247 return *this;
248 }
249 Optional &operator=(const Optional &O) = default;
250
251 void reset() { Storage.reset(); }
252
253 const T *getPointer() const { return &Storage.getValue(); }
254 T *getPointer() { return &Storage.getValue(); }
255 const T &getValue() const LLVM_LVALUE_FUNCTION& { return Storage.getValue(); }
256 T &getValue() LLVM_LVALUE_FUNCTION& { return Storage.getValue(); }
257
258 explicit operator bool() const { return hasValue(); }
23
Calling 'Optional::hasValue'
28
Returning from 'Optional::hasValue'
29
Returning zero, which participates in a condition later
32
Calling 'Optional::hasValue'
37
Returning from 'Optional::hasValue'
38
Returning zero, which participates in a condition later
259 bool hasValue() const { return Storage.hasValue(); }
24
Calling 'OptionalStorage::hasValue'
26
Returning from 'OptionalStorage::hasValue'
27
Returning zero, which participates in a condition later
33
Calling 'OptionalStorage::hasValue'
35
Returning from 'OptionalStorage::hasValue'
36
Returning zero, which participates in a condition later
260 const T *operator->() const { return getPointer(); }
261 T *operator->() { return getPointer(); }
262 const T &operator*() const LLVM_LVALUE_FUNCTION& { return getValue(); }
263 T &operator*() LLVM_LVALUE_FUNCTION& { return getValue(); }
264
265 template <typename U>
266 constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION& {
267 return hasValue() ? getValue() : std::forward<U>(value);
268 }
269
270 /// Apply a function to the value if present; otherwise return None.
271 template <class Function>
272 auto map(const Function &F) const LLVM_LVALUE_FUNCTION&
273 -> Optional<decltype(F(getValue()))> {
274 if (*this) return F(getValue());
275 return None;
276 }
277
278#if LLVM_HAS_RVALUE_REFERENCE_THIS1
279 T &&getValue() && { return std::move(Storage.getValue()); }
280 T &&operator*() && { return std::move(Storage.getValue()); }
281
282 template <typename U>
283 T getValueOr(U &&value) && {
284 return hasValue() ? std::move(getValue()) : std::forward<U>(value);
285 }
286
287 /// Apply a function to the value if present; otherwise return None.
288 template <class Function>
289 auto map(const Function &F) &&
290 -> Optional<decltype(F(std::move(*this).getValue()))> {
291 if (*this) return F(std::move(*this).getValue());
292 return None;
293 }
294#endif
295};
296
297template <typename T, typename U>
298bool operator==(const Optional<T> &X, const Optional<U> &Y) {
299 if (X && Y)
300 return *X == *Y;
301 return X.hasValue() == Y.hasValue();
302}
303
304template <typename T, typename U>
305bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
306 return !(X == Y);
307}
308
309template <typename T, typename U>
310bool operator<(const Optional<T> &X, const Optional<U> &Y) {
311 if (X && Y)
312 return *X < *Y;
313 return X.hasValue() < Y.hasValue();
314}
315
316template <typename T, typename U>
317bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
318 return !(Y < X);
319}
320
321template <typename T, typename U>
322bool operator>(const Optional<T> &X, const Optional<U> &Y) {
323 return Y < X;
324}
325
326template <typename T, typename U>
327bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
328 return !(X < Y);
329}
330
331template<typename T>
332bool operator==(const Optional<T> &X, NoneType) {
333 return !X;
334}
335
336template<typename T>
337bool operator==(NoneType, const Optional<T> &X) {
338 return X == None;
339}
340
341template<typename T>
342bool operator!=(const Optional<T> &X, NoneType) {
343 return !(X == None);
344}
345
346template<typename T>
347bool operator!=(NoneType, const Optional<T> &X) {
348 return X != None;
349}
350
351template <typename T> bool operator<(const Optional<T> &X, NoneType) {
352 return false;
353}
354
355template <typename T> bool operator<(NoneType, const Optional<T> &X) {
356 return X.hasValue();
357}
358
359template <typename T> bool operator<=(const Optional<T> &X, NoneType) {
360 return !(None < X);
361}
362
363template <typename T> bool operator<=(NoneType, const Optional<T> &X) {
364 return !(X < None);
365}
366
367template <typename T> bool operator>(const Optional<T> &X, NoneType) {
368 return None < X;
369}
370
371template <typename T> bool operator>(NoneType, const Optional<T> &X) {
372 return X < None;
373}
374
375template <typename T> bool operator>=(const Optional<T> &X, NoneType) {
376 return None <= X;
377}
378
379template <typename T> bool operator>=(NoneType, const Optional<T> &X) {
380 return X <= None;
381}
382
383template <typename T> bool operator==(const Optional<T> &X, const T &Y) {
384 return X && *X == Y;
385}
386
387template <typename T> bool operator==(const T &X, const Optional<T> &Y) {
388 return Y && X == *Y;
389}
390
391template <typename T> bool operator!=(const Optional<T> &X, const T &Y) {
392 return !(X == Y);
393}
394
395template <typename T> bool operator!=(const T &X, const Optional<T> &Y) {
396 return !(X == Y);
397}
398
399template <typename T> bool operator<(const Optional<T> &X, const T &Y) {
400 return !X || *X < Y;
401}
402
403template <typename T> bool operator<(const T &X, const Optional<T> &Y) {
404 return Y && X < *Y;
405}
406
407template <typename T> bool operator<=(const Optional<T> &X, const T &Y) {
408 return !(Y < X);
409}
410
411template <typename T> bool operator<=(const T &X, const Optional<T> &Y) {
412 return !(Y < X);
413}
414
415template <typename T> bool operator>(const Optional<T> &X, const T &Y) {
416 return Y < X;
417}
418
419template <typename T> bool operator>(const T &X, const Optional<T> &Y) {
420 return Y < X;
421}
422
423template <typename T> bool operator>=(const Optional<T> &X, const T &Y) {
424 return !(X < Y);
425}
426
427template <typename T> bool operator>=(const T &X, const Optional<T> &Y) {
428 return !(X < Y);
429}
430
431raw_ostream &operator<<(raw_ostream &OS, NoneType);
432
433template <typename T, typename = decltype(std::declval<raw_ostream &>()
434 << std::declval<const T &>())>
435raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) {
436 if (O)
437 OS << *O;
438 else
439 OS << None;
440 return OS;
441}
442
443} // end namespace llvm
444
445#endif // LLVM_ADT_OPTIONAL_H