Bug Summary

File:tools/clang/lib/Sema/SemaOpenMP.cpp
Warning:line 1360, column 38
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-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn326551/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.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++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn326551/build-llvm/tools/clang/lib/Sema -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-03-02-155150-1477-1 -x c++ /build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp
1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// \brief This file implements semantic analysis for OpenMP directives and
11/// clauses.
12///
13//===----------------------------------------------------------------------===//
14
15#include "TreeTransform.h"
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/ASTMutationListener.h"
18#include "clang/AST/CXXInheritance.h"
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
21#include "clang/AST/DeclOpenMP.h"
22#include "clang/AST/StmtCXX.h"
23#include "clang/AST/StmtOpenMP.h"
24#include "clang/AST/StmtVisitor.h"
25#include "clang/Basic/OpenMPKinds.h"
26#include "clang/Sema/Initialization.h"
27#include "clang/Sema/Lookup.h"
28#include "clang/Sema/Scope.h"
29#include "clang/Sema/ScopeInfo.h"
30#include "clang/Sema/SemaInternal.h"
31#include "llvm/ADT/PointerEmbeddedInt.h"
32using namespace clang;
33
34//===----------------------------------------------------------------------===//
35// Stack of data-sharing attributes for variables
36//===----------------------------------------------------------------------===//
37
38static Expr *CheckMapClauseExpressionBase(
39 Sema &SemaRef, Expr *E,
40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41 OpenMPClauseKind CKind, bool NoDiagnose);
42
43namespace {
44/// \brief Default data sharing attributes, which can be applied to directive.
45enum DefaultDataSharingAttributes {
46 DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
47 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
48 DSA_shared = 1 << 1, /// \brief Default data sharing attribute 'shared'.
49};
50
51/// Attributes of the defaultmap clause.
52enum DefaultMapAttributes {
53 DMA_unspecified, /// Default mapping is not specified.
54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
55};
56
57/// \brief Stack for tracking declarations used in OpenMP directives and
58/// clauses and their data-sharing attributes.
59class DSAStackTy final {
60public:
61 struct DSAVarData final {
62 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
64 Expr *RefExpr = nullptr;
65 DeclRefExpr *PrivateCopy = nullptr;
66 SourceLocation ImplicitDSALoc;
67 DSAVarData() = default;
68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
69 DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
70 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
71 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
72 };
73 typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>
74 OperatorOffsetTy;
75
76private:
77 struct DSAInfo final {
78 OpenMPClauseKind Attributes = OMPC_unknown;
79 /// Pointer to a reference expression and a flag which shows that the
80 /// variable is marked as lastprivate(true) or not (false).
81 llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
82 DeclRefExpr *PrivateCopy = nullptr;
83 };
84 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
85 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
86 typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
87 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
88 /// Struct that associates a component with the clause kind where they are
89 /// found.
90 struct MappedExprComponentTy {
91 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
92 OpenMPClauseKind Kind = OMPC_unknown;
93 };
94 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
95 MappedExprComponentsTy;
96 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
97 CriticalsWithHintsTy;
98 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
99 DoacrossDependMapTy;
100 struct ReductionData {
101 typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType;
102 SourceRange ReductionRange;
103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104 ReductionData() = default;
105 void set(BinaryOperatorKind BO, SourceRange RR) {
106 ReductionRange = RR;
107 ReductionOp = BO;
108 }
109 void set(const Expr *RefExpr, SourceRange RR) {
110 ReductionRange = RR;
111 ReductionOp = RefExpr;
112 }
113 };
114 typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy;
115
116 struct SharingMapTy final {
117 DeclSAMapTy SharingMap;
118 DeclReductionMapTy ReductionMap;
119 AlignedMapTy AlignedMap;
120 MappedExprComponentsTy MappedExprComponents;
121 LoopControlVariablesMapTy LCVMap;
122 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
123 SourceLocation DefaultAttrLoc;
124 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
125 SourceLocation DefaultMapAttrLoc;
126 OpenMPDirectiveKind Directive = OMPD_unknown;
127 DeclarationNameInfo DirectiveName;
128 Scope *CurScope = nullptr;
129 SourceLocation ConstructLoc;
130 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
131 /// get the data (loop counters etc.) about enclosing loop-based construct.
132 /// This data is required during codegen.
133 DoacrossDependMapTy DoacrossDepends;
134 /// \brief first argument (Expr *) contains optional argument of the
135 /// 'ordered' clause, the second one is true if the regions has 'ordered'
136 /// clause, false otherwise.
137 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
138 bool NowaitRegion = false;
139 bool CancelRegion = false;
140 unsigned AssociatedLoops = 1;
141 SourceLocation InnerTeamsRegionLoc;
142 /// Reference to the taskgroup task_reduction reference expression.
143 Expr *TaskgroupReductionRef = nullptr;
144 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
145 Scope *CurScope, SourceLocation Loc)
146 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
147 ConstructLoc(Loc) {}
148 SharingMapTy() = default;
149 };
150
151 typedef SmallVector<SharingMapTy, 4> StackTy;
152
153 /// \brief Stack of used declaration and their data-sharing attributes.
154 DeclSAMapTy Threadprivates;
155 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
156 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
157 /// \brief true, if check for DSA must be from parent directive, false, if
158 /// from current directive.
159 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
160 Sema &SemaRef;
161 bool ForceCapturing = false;
162 CriticalsWithHintsTy Criticals;
163
164 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
165
166 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D);
167
168 /// \brief Checks if the variable is a local for OpenMP region.
169 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
170
171 bool isStackEmpty() const {
172 return Stack.empty() ||
173 Stack.back().second != CurrentNonCapturingFunctionScope ||
174 Stack.back().first.empty();
175 }
176
177public:
178 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
179
180 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
181 OpenMPClauseKind getClauseParsingMode() const {
182 assert(isClauseParsingMode() && "Must be in clause parsing mode.")(static_cast <bool> (isClauseParsingMode() && "Must be in clause parsing mode."
) ? void (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 182, __extension__ __PRETTY_FUNCTION__))
;
183 return ClauseKindMode;
184 }
185 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
186
187 bool isForceVarCapturing() const { return ForceCapturing; }
188 void setForceVarCapturing(bool V) { ForceCapturing = V; }
189
190 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
191 Scope *CurScope, SourceLocation Loc) {
192 if (Stack.empty() ||
193 Stack.back().second != CurrentNonCapturingFunctionScope)
194 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
195 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
196 Stack.back().first.back().DefaultAttrLoc = Loc;
197 }
198
199 void pop() {
200 assert(!Stack.back().first.empty() &&(static_cast <bool> (!Stack.back().first.empty() &&
"Data-sharing attributes stack is empty!") ? void (0) : __assert_fail
("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 201, __extension__ __PRETTY_FUNCTION__))
201 "Data-sharing attributes stack is empty!")(static_cast <bool> (!Stack.back().first.empty() &&
"Data-sharing attributes stack is empty!") ? void (0) : __assert_fail
("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 201, __extension__ __PRETTY_FUNCTION__))
;
202 Stack.back().first.pop_back();
203 }
204
205 /// Start new OpenMP region stack in new non-capturing function.
206 void pushFunction() {
207 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
208 assert(!isa<CapturingScopeInfo>(CurFnScope))(static_cast <bool> (!isa<CapturingScopeInfo>(CurFnScope
)) ? void (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 208, __extension__ __PRETTY_FUNCTION__))
;
209 CurrentNonCapturingFunctionScope = CurFnScope;
210 }
211 /// Pop region stack for non-capturing function.
212 void popFunction(const FunctionScopeInfo *OldFSI) {
213 if (!Stack.empty() && Stack.back().second == OldFSI) {
214 assert(Stack.back().first.empty())(static_cast <bool> (Stack.back().first.empty()) ? void
(0) : __assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 214, __extension__ __PRETTY_FUNCTION__))
;
215 Stack.pop_back();
216 }
217 CurrentNonCapturingFunctionScope = nullptr;
218 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
219 if (!isa<CapturingScopeInfo>(FSI)) {
220 CurrentNonCapturingFunctionScope = FSI;
221 break;
222 }
223 }
224 }
225
226 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
227 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
228 }
229 const std::pair<OMPCriticalDirective *, llvm::APSInt>
230 getCriticalWithHint(const DeclarationNameInfo &Name) const {
231 auto I = Criticals.find(Name.getAsString());
232 if (I != Criticals.end())
233 return I->second;
234 return std::make_pair(nullptr, llvm::APSInt());
235 }
236 /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
237 /// add it and return NULL; otherwise return previous occurrence's expression
238 /// for diagnostics.
239 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE);
240
241 /// \brief Register specified variable as loop control variable.
242 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture);
243 /// \brief Check if the specified variable is a loop control variable for
244 /// current region.
245 /// \return The index of the loop control variable in the list of associated
246 /// for-loops (from outer to inner).
247 LCDeclInfo isLoopControlVariable(ValueDecl *D);
248 /// \brief Check if the specified variable is a loop control variable for
249 /// parent region.
250 /// \return The index of the loop control variable in the list of associated
251 /// for-loops (from outer to inner).
252 LCDeclInfo isParentLoopControlVariable(ValueDecl *D);
253 /// \brief Get the loop control variable for the I-th loop (or nullptr) in
254 /// parent directive.
255 ValueDecl *getParentLoopControlVariable(unsigned I);
256
257 /// \brief Adds explicit data sharing attribute to the specified declaration.
258 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
259 DeclRefExpr *PrivateCopy = nullptr);
260
261 /// Adds additional information for the reduction items with the reduction id
262 /// represented as an operator.
263 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
264 BinaryOperatorKind BOK);
265 /// Adds additional information for the reduction items with the reduction id
266 /// represented as reduction identifier.
267 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
268 const Expr *ReductionRef);
269 /// Returns the location and reduction operation from the innermost parent
270 /// region for the given \p D.
271 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
272 BinaryOperatorKind &BOK,
273 Expr *&TaskgroupDescriptor);
274 /// Returns the location and reduction operation from the innermost parent
275 /// region for the given \p D.
276 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
277 const Expr *&ReductionRef,
278 Expr *&TaskgroupDescriptor);
279 /// Return reduction reference expression for the current taskgroup.
280 Expr *getTaskgroupReductionRef() const {
281 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&(static_cast <bool> (Stack.back().first.back().Directive
== OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? void (0) : __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 283, __extension__ __PRETTY_FUNCTION__))
282 "taskgroup reference expression requested for non taskgroup "(static_cast <bool> (Stack.back().first.back().Directive
== OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? void (0) : __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 283, __extension__ __PRETTY_FUNCTION__))
283 "directive.")(static_cast <bool> (Stack.back().first.back().Directive
== OMPD_taskgroup && "taskgroup reference expression requested for non taskgroup "
"directive.") ? void (0) : __assert_fail ("Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 283, __extension__ __PRETTY_FUNCTION__))
;
284 return Stack.back().first.back().TaskgroupReductionRef;
285 }
286 /// Checks if the given \p VD declaration is actually a taskgroup reduction
287 /// descriptor variable at the \p Level of OpenMP regions.
288 bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const {
289 return Stack.back().first[Level].TaskgroupReductionRef &&
290 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
291 ->getDecl() == VD;
292 }
293
294 /// \brief Returns data sharing attributes from top of the stack for the
295 /// specified declaration.
296 DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
297 /// \brief Returns data-sharing attributes for the specified declaration.
298 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent);
299 /// \brief Checks if the specified variables has data-sharing attributes which
300 /// match specified \a CPred predicate in any directive which matches \a DPred
301 /// predicate.
302 DSAVarData hasDSA(ValueDecl *D,
303 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
304 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
305 bool FromParent);
306 /// \brief Checks if the specified variables has data-sharing attributes which
307 /// match specified \a CPred predicate in any innermost directive which
308 /// matches \a DPred predicate.
309 DSAVarData
310 hasInnermostDSA(ValueDecl *D,
311 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
312 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
313 bool FromParent);
314 /// \brief Checks if the specified variables has explicit data-sharing
315 /// attributes which match specified \a CPred predicate at the specified
316 /// OpenMP region.
317 bool hasExplicitDSA(ValueDecl *D,
318 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
319 unsigned Level, bool NotLastprivate = false);
320
321 /// \brief Returns true if the directive at level \Level matches in the
322 /// specified \a DPred predicate.
323 bool hasExplicitDirective(
324 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
325 unsigned Level);
326
327 /// \brief Finds a directive which matches specified \a DPred predicate.
328 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind,
329 const DeclarationNameInfo &,
330 SourceLocation)> &DPred,
331 bool FromParent);
332
333 /// \brief Returns currently analyzed directive.
334 OpenMPDirectiveKind getCurrentDirective() const {
335 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
336 }
337 /// \brief Returns directive kind at specified level.
338 OpenMPDirectiveKind getDirective(unsigned Level) const {
339 assert(!isStackEmpty() && "No directive at specified level.")(static_cast <bool> (!isStackEmpty() && "No directive at specified level."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 339, __extension__ __PRETTY_FUNCTION__))
;
340 return Stack.back().first[Level].Directive;
341 }
342 /// \brief Returns parent directive.
343 OpenMPDirectiveKind getParentDirective() const {
344 if (isStackEmpty() || Stack.back().first.size() == 1)
345 return OMPD_unknown;
346 return std::next(Stack.back().first.rbegin())->Directive;
347 }
348
349 /// \brief Set default data sharing attribute to none.
350 void setDefaultDSANone(SourceLocation Loc) {
351 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 351, __extension__ __PRETTY_FUNCTION__))
;
352 Stack.back().first.back().DefaultAttr = DSA_none;
353 Stack.back().first.back().DefaultAttrLoc = Loc;
354 }
355 /// \brief Set default data sharing attribute to shared.
356 void setDefaultDSAShared(SourceLocation Loc) {
357 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 357, __extension__ __PRETTY_FUNCTION__))
;
358 Stack.back().first.back().DefaultAttr = DSA_shared;
359 Stack.back().first.back().DefaultAttrLoc = Loc;
360 }
361 /// Set default data mapping attribute to 'tofrom:scalar'.
362 void setDefaultDMAToFromScalar(SourceLocation Loc) {
363 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 363, __extension__ __PRETTY_FUNCTION__))
;
364 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
365 Stack.back().first.back().DefaultMapAttrLoc = Loc;
366 }
367
368 DefaultDataSharingAttributes getDefaultDSA() const {
369 return isStackEmpty() ? DSA_unspecified
370 : Stack.back().first.back().DefaultAttr;
371 }
372 SourceLocation getDefaultDSALocation() const {
373 return isStackEmpty() ? SourceLocation()
374 : Stack.back().first.back().DefaultAttrLoc;
375 }
376 DefaultMapAttributes getDefaultDMA() const {
377 return isStackEmpty() ? DMA_unspecified
378 : Stack.back().first.back().DefaultMapAttr;
379 }
380 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
381 return Stack.back().first[Level].DefaultMapAttr;
382 }
383 SourceLocation getDefaultDMALocation() const {
384 return isStackEmpty() ? SourceLocation()
385 : Stack.back().first.back().DefaultMapAttrLoc;
386 }
387
388 /// \brief Checks if the specified variable is a threadprivate.
389 bool isThreadPrivate(VarDecl *D) {
390 DSAVarData DVar = getTopDSA(D, false);
391 return isOpenMPThreadPrivate(DVar.CKind);
392 }
393
394 /// \brief Marks current region as ordered (it has an 'ordered' clause).
395 void setOrderedRegion(bool IsOrdered, Expr *Param) {
396 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 396, __extension__ __PRETTY_FUNCTION__))
;
397 Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
398 Stack.back().first.back().OrderedRegion.setPointer(Param);
399 }
400 /// \brief Returns true, if parent region is ordered (has associated
401 /// 'ordered' clause), false - otherwise.
402 bool isParentOrderedRegion() const {
403 if (isStackEmpty() || Stack.back().first.size() == 1)
404 return false;
405 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
406 }
407 /// \brief Returns optional parameter for the ordered region.
408 Expr *getParentOrderedRegionParam() const {
409 if (isStackEmpty() || Stack.back().first.size() == 1)
410 return nullptr;
411 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
412 }
413 /// \brief Marks current region as nowait (it has a 'nowait' clause).
414 void setNowaitRegion(bool IsNowait = true) {
415 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 415, __extension__ __PRETTY_FUNCTION__))
;
416 Stack.back().first.back().NowaitRegion = IsNowait;
417 }
418 /// \brief Returns true, if parent region is nowait (has associated
419 /// 'nowait' clause), false - otherwise.
420 bool isParentNowaitRegion() const {
421 if (isStackEmpty() || Stack.back().first.size() == 1)
422 return false;
423 return std::next(Stack.back().first.rbegin())->NowaitRegion;
424 }
425 /// \brief Marks parent region as cancel region.
426 void setParentCancelRegion(bool Cancel = true) {
427 if (!isStackEmpty() && Stack.back().first.size() > 1) {
428 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
429 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
430 }
431 }
432 /// \brief Return true if current region has inner cancel construct.
433 bool isCancelRegion() const {
434 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
435 }
436
437 /// \brief Set collapse value for the region.
438 void setAssociatedLoops(unsigned Val) {
439 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 439, __extension__ __PRETTY_FUNCTION__))
;
440 Stack.back().first.back().AssociatedLoops = Val;
441 }
442 /// \brief Return collapse value for region.
443 unsigned getAssociatedLoops() const {
444 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
445 }
446
447 /// \brief Marks current target region as one with closely nested teams
448 /// region.
449 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
450 if (!isStackEmpty() && Stack.back().first.size() > 1) {
451 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
452 TeamsRegionLoc;
453 }
454 }
455 /// \brief Returns true, if current region has closely nested teams region.
456 bool hasInnerTeamsRegion() const {
457 return getInnerTeamsRegionLoc().isValid();
458 }
459 /// \brief Returns location of the nested teams region (if any).
460 SourceLocation getInnerTeamsRegionLoc() const {
461 return isStackEmpty() ? SourceLocation()
462 : Stack.back().first.back().InnerTeamsRegionLoc;
463 }
464
465 Scope *getCurScope() const {
466 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
467 }
468 Scope *getCurScope() {
469 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
470 }
471 SourceLocation getConstructLoc() {
472 return isStackEmpty() ? SourceLocation()
473 : Stack.back().first.back().ConstructLoc;
474 }
475
476 /// Do the check specified in \a Check to all component lists and return true
477 /// if any issue is found.
478 bool checkMappableExprComponentListsForDecl(
479 ValueDecl *VD, bool CurrentRegionOnly,
480 const llvm::function_ref<
481 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
482 OpenMPClauseKind)> &Check) {
483 if (isStackEmpty())
484 return false;
485 auto SI = Stack.back().first.rbegin();
486 auto SE = Stack.back().first.rend();
487
488 if (SI == SE)
489 return false;
490
491 if (CurrentRegionOnly) {
492 SE = std::next(SI);
493 } else {
494 ++SI;
495 }
496
497 for (; SI != SE; ++SI) {
498 auto MI = SI->MappedExprComponents.find(VD);
499 if (MI != SI->MappedExprComponents.end())
500 for (auto &L : MI->second.Components)
501 if (Check(L, MI->second.Kind))
502 return true;
503 }
504 return false;
505 }
506
507 /// Do the check specified in \a Check to all component lists at a given level
508 /// and return true if any issue is found.
509 bool checkMappableExprComponentListsForDeclAtLevel(
510 ValueDecl *VD, unsigned Level,
511 const llvm::function_ref<
512 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
513 OpenMPClauseKind)> &Check) {
514 if (isStackEmpty())
515 return false;
516
517 auto StartI = Stack.back().first.begin();
518 auto EndI = Stack.back().first.end();
519 if (std::distance(StartI, EndI) <= (int)Level)
520 return false;
521 std::advance(StartI, Level);
522
523 auto MI = StartI->MappedExprComponents.find(VD);
524 if (MI != StartI->MappedExprComponents.end())
525 for (auto &L : MI->second.Components)
526 if (Check(L, MI->second.Kind))
527 return true;
528 return false;
529 }
530
531 /// Create a new mappable expression component list associated with a given
532 /// declaration and initialize it with the provided list of components.
533 void addMappableExpressionComponents(
534 ValueDecl *VD,
535 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
536 OpenMPClauseKind WhereFoundClauseKind) {
537 assert(!isStackEmpty() &&(static_cast <bool> (!isStackEmpty() && "Not expecting to retrieve components from a empty stack!"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 538, __extension__ __PRETTY_FUNCTION__))
538 "Not expecting to retrieve components from a empty stack!")(static_cast <bool> (!isStackEmpty() && "Not expecting to retrieve components from a empty stack!"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 538, __extension__ __PRETTY_FUNCTION__))
;
539 auto &MEC = Stack.back().first.back().MappedExprComponents[VD];
540 // Create new entry and append the new components there.
541 MEC.Components.resize(MEC.Components.size() + 1);
542 MEC.Components.back().append(Components.begin(), Components.end());
543 MEC.Kind = WhereFoundClauseKind;
544 }
545
546 unsigned getNestingLevel() const {
547 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 547, __extension__ __PRETTY_FUNCTION__))
;
548 return Stack.back().first.size() - 1;
549 }
550 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
551 assert(!isStackEmpty() && Stack.back().first.size() > 1)(static_cast <bool> (!isStackEmpty() && Stack.back
().first.size() > 1) ? void (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 551, __extension__ __PRETTY_FUNCTION__))
;
552 auto &StackElem = *std::next(Stack.back().first.rbegin());
553 assert(isOpenMPWorksharingDirective(StackElem.Directive))(static_cast <bool> (isOpenMPWorksharingDirective(StackElem
.Directive)) ? void (0) : __assert_fail ("isOpenMPWorksharingDirective(StackElem.Directive)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 553, __extension__ __PRETTY_FUNCTION__))
;
554 StackElem.DoacrossDepends.insert({C, OpsOffs});
555 }
556 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
557 getDoacrossDependClauses() const {
558 assert(!isStackEmpty())(static_cast <bool> (!isStackEmpty()) ? void (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 558, __extension__ __PRETTY_FUNCTION__))
;
559 auto &StackElem = Stack.back().first.back();
560 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
561 auto &Ref = StackElem.DoacrossDepends;
562 return llvm::make_range(Ref.begin(), Ref.end());
563 }
564 return llvm::make_range(StackElem.DoacrossDepends.end(),
565 StackElem.DoacrossDepends.end());
566 }
567};
568bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
569 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
570 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
571}
572} // namespace
573
574static Expr *getExprAsWritten(Expr *E) {
575 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
576 E = ExprTemp->getSubExpr();
577
578 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
579 E = MTE->GetTemporaryExpr();
580
581 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
582 E = Binder->getSubExpr();
583
584 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
585 E = ICE->getSubExprAsWritten();
586 return E->IgnoreParens();
587}
588
589static ValueDecl *getCanonicalDecl(ValueDecl *D) {
590 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
591 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
592 D = ME->getMemberDecl();
593 auto *VD = dyn_cast<VarDecl>(D);
594 auto *FD = dyn_cast<FieldDecl>(D);
595 if (VD != nullptr) {
596 VD = VD->getCanonicalDecl();
597 D = VD;
598 } else {
599 assert(FD)(static_cast <bool> (FD) ? void (0) : __assert_fail ("FD"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 599, __extension__ __PRETTY_FUNCTION__))
;
600 FD = FD->getCanonicalDecl();
601 D = FD;
602 }
603 return D;
604}
605
606DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
607 ValueDecl *D) {
608 D = getCanonicalDecl(D);
609 auto *VD = dyn_cast<VarDecl>(D);
610 auto *FD = dyn_cast<FieldDecl>(D);
611 DSAVarData DVar;
612 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
613 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
614 // in a region but not in construct]
615 // File-scope or namespace-scope variables referenced in called routines
616 // in the region are shared unless they appear in a threadprivate
617 // directive.
618 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
619 DVar.CKind = OMPC_shared;
620
621 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
622 // in a region but not in construct]
623 // Variables with static storage duration that are declared in called
624 // routines in the region are shared.
625 if (VD && VD->hasGlobalStorage())
626 DVar.CKind = OMPC_shared;
627
628 // Non-static data members are shared by default.
629 if (FD)
630 DVar.CKind = OMPC_shared;
631
632 return DVar;
633 }
634
635 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
636 // in a Construct, C/C++, predetermined, p.1]
637 // Variables with automatic storage duration that are declared in a scope
638 // inside the construct are private.
639 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
640 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
641 DVar.CKind = OMPC_private;
642 return DVar;
643 }
644
645 DVar.DKind = Iter->Directive;
646 // Explicitly specified attributes and local variables with predetermined
647 // attributes.
648 if (Iter->SharingMap.count(D)) {
649 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
650 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
651 DVar.CKind = Iter->SharingMap[D].Attributes;
652 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
653 return DVar;
654 }
655
656 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
657 // in a Construct, C/C++, implicitly determined, p.1]
658 // In a parallel or task construct, the data-sharing attributes of these
659 // variables are determined by the default clause, if present.
660 switch (Iter->DefaultAttr) {
661 case DSA_shared:
662 DVar.CKind = OMPC_shared;
663 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
664 return DVar;
665 case DSA_none:
666 return DVar;
667 case DSA_unspecified:
668 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
669 // in a Construct, implicitly determined, p.2]
670 // In a parallel construct, if no default clause is present, these
671 // variables are shared.
672 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
673 if (isOpenMPParallelDirective(DVar.DKind) ||
674 isOpenMPTeamsDirective(DVar.DKind)) {
675 DVar.CKind = OMPC_shared;
676 return DVar;
677 }
678
679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
680 // in a Construct, implicitly determined, p.4]
681 // In a task construct, if no default clause is present, a variable that in
682 // the enclosing context is determined to be shared by all implicit tasks
683 // bound to the current team is shared.
684 if (isOpenMPTaskingDirective(DVar.DKind)) {
685 DSAVarData DVarTemp;
686 auto I = Iter, E = Stack.back().first.rend();
687 do {
688 ++I;
689 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
690 // Referenced in a Construct, implicitly determined, p.6]
691 // In a task construct, if no default clause is present, a variable
692 // whose data-sharing attribute is not determined by the rules above is
693 // firstprivate.
694 DVarTemp = getDSA(I, D);
695 if (DVarTemp.CKind != OMPC_shared) {
696 DVar.RefExpr = nullptr;
697 DVar.CKind = OMPC_firstprivate;
698 return DVar;
699 }
700 } while (I != E && !isParallelOrTaskRegion(I->Directive));
701 DVar.CKind =
702 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
703 return DVar;
704 }
705 }
706 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707 // in a Construct, implicitly determined, p.3]
708 // For constructs other than task, if no default clause is present, these
709 // variables inherit their data-sharing attributes from the enclosing
710 // context.
711 return getDSA(++Iter, D);
712}
713
714Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {
715 assert(!isStackEmpty() && "Data sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 715, __extension__ __PRETTY_FUNCTION__))
;
716 D = getCanonicalDecl(D);
717 auto &StackElem = Stack.back().first.back();
718 auto It = StackElem.AlignedMap.find(D);
719 if (It == StackElem.AlignedMap.end()) {
720 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")(static_cast <bool> (NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? void (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 720, __extension__ __PRETTY_FUNCTION__))
;
721 StackElem.AlignedMap[D] = NewDE;
722 return nullptr;
723 } else {
724 assert(It->second && "Unexpected nullptr expr in the aligned map")(static_cast <bool> (It->second && "Unexpected nullptr expr in the aligned map"
) ? void (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 724, __extension__ __PRETTY_FUNCTION__))
;
725 return It->second;
726 }
727 return nullptr;
728}
729
730void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {
731 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 731, __extension__ __PRETTY_FUNCTION__))
;
732 D = getCanonicalDecl(D);
733 auto &StackElem = Stack.back().first.back();
734 StackElem.LCVMap.insert(
735 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
736}
737
738DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {
739 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 739, __extension__ __PRETTY_FUNCTION__))
;
740 D = getCanonicalDecl(D);
741 auto &StackElem = Stack.back().first.back();
742 auto It = StackElem.LCVMap.find(D);
743 if (It != StackElem.LCVMap.end())
744 return It->second;
745 return {0, nullptr};
746}
747
748DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {
749 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&(static_cast <bool> (!isStackEmpty() && Stack.back
().first.size() > 1 && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 750, __extension__ __PRETTY_FUNCTION__))
750 "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && Stack.back
().first.size() > 1 && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 750, __extension__ __PRETTY_FUNCTION__))
;
751 D = getCanonicalDecl(D);
752 auto &StackElem = *std::next(Stack.back().first.rbegin());
753 auto It = StackElem.LCVMap.find(D);
754 if (It != StackElem.LCVMap.end())
755 return It->second;
756 return {0, nullptr};
757}
758
759ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
760 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&(static_cast <bool> (!isStackEmpty() && Stack.back
().first.size() > 1 && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 761, __extension__ __PRETTY_FUNCTION__))
761 "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && Stack.back
().first.size() > 1 && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 761, __extension__ __PRETTY_FUNCTION__))
;
762 auto &StackElem = *std::next(Stack.back().first.rbegin());
763 if (StackElem.LCVMap.size() < I)
764 return nullptr;
765 for (auto &Pair : StackElem.LCVMap)
766 if (Pair.second.first == I)
767 return Pair.first;
768 return nullptr;
769}
770
771void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
772 DeclRefExpr *PrivateCopy) {
773 D = getCanonicalDecl(D);
774 if (A == OMPC_threadprivate) {
775 auto &Data = Threadprivates[D];
776 Data.Attributes = A;
777 Data.RefExpr.setPointer(E);
778 Data.PrivateCopy = nullptr;
779 } else {
780 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 780, __extension__ __PRETTY_FUNCTION__))
;
781 auto &Data = Stack.back().first.back().SharingMap[D];
782 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 785, __extension__ __PRETTY_FUNCTION__))
783 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 785, __extension__ __PRETTY_FUNCTION__))
784 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 785, __extension__ __PRETTY_FUNCTION__))
785 (isLoopControlVariable(D).first && A == OMPC_private))(static_cast <bool> (Data.Attributes == OMPC_unknown ||
(A == Data.Attributes) || (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate
&& Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable
(D).first && A == OMPC_private)) ? void (0) : __assert_fail
("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 785, __extension__ __PRETTY_FUNCTION__))
;
786 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
787 Data.RefExpr.setInt(/*IntVal=*/true);
788 return;
789 }
790 const bool IsLastprivate =
791 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
792 Data.Attributes = A;
793 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
794 Data.PrivateCopy = PrivateCopy;
795 if (PrivateCopy) {
796 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
797 Data.Attributes = A;
798 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
799 Data.PrivateCopy = nullptr;
800 }
801 }
802}
803
804/// \brief Build a variable declaration for OpenMP loop iteration variable.
805static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
806 StringRef Name, const AttrVec *Attrs = nullptr) {
807 DeclContext *DC = SemaRef.CurContext;
808 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
809 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
810 VarDecl *Decl =
811 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
812 if (Attrs) {
813 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
814 I != E; ++I)
815 Decl->addAttr(*I);
816 }
817 Decl->setImplicit();
818 return Decl;
819}
820
821static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
822 SourceLocation Loc,
823 bool RefersToCapture = false) {
824 D->setReferenced();
825 D->markUsed(S.Context);
826 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
827 SourceLocation(), D, RefersToCapture, Loc, Ty,
828 VK_LValue);
829}
830
831void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
832 BinaryOperatorKind BOK) {
833 D = getCanonicalDecl(D);
834 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 834, __extension__ __PRETTY_FUNCTION__))
;
835 assert((static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 837, __extension__ __PRETTY_FUNCTION__))
836 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&(static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 837, __extension__ __PRETTY_FUNCTION__))
837 "Additional reduction info may be specified only for reduction items.")(static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 837, __extension__ __PRETTY_FUNCTION__))
;
838 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
839 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 842, __extension__ __PRETTY_FUNCTION__))
840 Stack.back().first.back().Directive == OMPD_taskgroup &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 842, __extension__ __PRETTY_FUNCTION__))
841 "Additional reduction info may be specified only once for reduction "(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 842, __extension__ __PRETTY_FUNCTION__))
842 "items.")(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 842, __extension__ __PRETTY_FUNCTION__))
;
843 ReductionData.set(BOK, SR);
844 Expr *&TaskgroupReductionRef =
845 Stack.back().first.back().TaskgroupReductionRef;
846 if (!TaskgroupReductionRef) {
847 auto *VD = buildVarDecl(SemaRef, SR.getBegin(),
848 SemaRef.Context.VoidPtrTy, ".task_red.");
849 TaskgroupReductionRef =
850 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
851 }
852}
853
854void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
855 const Expr *ReductionRef) {
856 D = getCanonicalDecl(D);
857 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 857, __extension__ __PRETTY_FUNCTION__))
;
858 assert((static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 860, __extension__ __PRETTY_FUNCTION__))
859 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&(static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 860, __extension__ __PRETTY_FUNCTION__))
860 "Additional reduction info may be specified only for reduction items.")(static_cast <bool> (Stack.back().first.back().SharingMap
[D].Attributes == OMPC_reduction && "Additional reduction info may be specified only for reduction items."
) ? void (0) : __assert_fail ("Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && \"Additional reduction info may be specified only for reduction items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 860, __extension__ __PRETTY_FUNCTION__))
;
861 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
862 assert(ReductionData.ReductionRange.isInvalid() &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 865, __extension__ __PRETTY_FUNCTION__))
863 Stack.back().first.back().Directive == OMPD_taskgroup &&(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 865, __extension__ __PRETTY_FUNCTION__))
864 "Additional reduction info may be specified only once for reduction "(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 865, __extension__ __PRETTY_FUNCTION__))
865 "items.")(static_cast <bool> (ReductionData.ReductionRange.isInvalid
() && Stack.back().first.back().Directive == OMPD_taskgroup
&& "Additional reduction info may be specified only once for reduction "
"items.") ? void (0) : __assert_fail ("ReductionData.ReductionRange.isInvalid() && Stack.back().first.back().Directive == OMPD_taskgroup && \"Additional reduction info may be specified only once for reduction \" \"items.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 865, __extension__ __PRETTY_FUNCTION__))
;
866 ReductionData.set(ReductionRef, SR);
867 Expr *&TaskgroupReductionRef =
868 Stack.back().first.back().TaskgroupReductionRef;
869 if (!TaskgroupReductionRef) {
870 auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy,
871 ".task_red.");
872 TaskgroupReductionRef =
873 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
874 }
875}
876
877DSAStackTy::DSAVarData
878DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
879 BinaryOperatorKind &BOK,
880 Expr *&TaskgroupDescriptor) {
881 D = getCanonicalDecl(D);
882 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 882, __extension__ __PRETTY_FUNCTION__))
;
883 if (Stack.back().first.empty())
884 return DSAVarData();
885 for (auto I = std::next(Stack.back().first.rbegin(), 1),
886 E = Stack.back().first.rend();
887 I != E; std::advance(I, 1)) {
888 auto &Data = I->SharingMap[D];
889 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
890 continue;
891 auto &ReductionData = I->ReductionMap[D];
892 if (!ReductionData.ReductionOp ||
893 ReductionData.ReductionOp.is<const Expr *>())
894 return DSAVarData();
895 SR = ReductionData.ReductionRange;
896 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
897 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 899, __extension__ __PRETTY_FUNCTION__))
898 "expression for the descriptor is not "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 899, __extension__ __PRETTY_FUNCTION__))
899 "set.")(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 899, __extension__ __PRETTY_FUNCTION__))
;
900 TaskgroupDescriptor = I->TaskgroupReductionRef;
901 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
902 Data.PrivateCopy, I->DefaultAttrLoc);
903 }
904 return DSAVarData();
905}
906
907DSAStackTy::DSAVarData
908DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
909 const Expr *&ReductionRef,
910 Expr *&TaskgroupDescriptor) {
911 D = getCanonicalDecl(D);
912 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")(static_cast <bool> (!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? void (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 912, __extension__ __PRETTY_FUNCTION__))
;
913 if (Stack.back().first.empty())
914 return DSAVarData();
915 for (auto I = std::next(Stack.back().first.rbegin(), 1),
916 E = Stack.back().first.rend();
917 I != E; std::advance(I, 1)) {
918 auto &Data = I->SharingMap[D];
919 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
920 continue;
921 auto &ReductionData = I->ReductionMap[D];
922 if (!ReductionData.ReductionOp ||
923 !ReductionData.ReductionOp.is<const Expr *>())
924 return DSAVarData();
925 SR = ReductionData.ReductionRange;
926 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
927 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 929, __extension__ __PRETTY_FUNCTION__))
928 "expression for the descriptor is not "(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 929, __extension__ __PRETTY_FUNCTION__))
929 "set.")(static_cast <bool> (I->TaskgroupReductionRef &&
"taskgroup reduction reference " "expression for the descriptor is not "
"set.") ? void (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 929, __extension__ __PRETTY_FUNCTION__))
;
930 TaskgroupDescriptor = I->TaskgroupReductionRef;
931 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
932 Data.PrivateCopy, I->DefaultAttrLoc);
933 }
934 return DSAVarData();
935}
936
937bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
938 D = D->getCanonicalDecl();
939 if (!isStackEmpty() && Stack.back().first.size() > 1) {
940 reverse_iterator I = Iter, E = Stack.back().first.rend();
941 Scope *TopScope = nullptr;
942 while (I != E && !isParallelOrTaskRegion(I->Directive))
943 ++I;
944 if (I == E)
945 return false;
946 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
947 Scope *CurScope = getCurScope();
948 while (CurScope != TopScope && !CurScope->isDeclScope(D))
949 CurScope = CurScope->getParent();
950 return CurScope != TopScope;
951 }
952 return false;
953}
954
955DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
956 D = getCanonicalDecl(D);
957 DSAVarData DVar;
958
959 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
960 // in a Construct, C/C++, predetermined, p.1]
961 // Variables appearing in threadprivate directives are threadprivate.
962 auto *VD = dyn_cast<VarDecl>(D);
963 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
964 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
965 SemaRef.getLangOpts().OpenMPUseTLS &&
966 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
967 (VD && VD->getStorageClass() == SC_Register &&
968 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
969 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
970 D->getLocation()),
971 OMPC_threadprivate);
972 }
973 auto TI = Threadprivates.find(D);
974 if (TI != Threadprivates.end()) {
975 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
976 DVar.CKind = OMPC_threadprivate;
977 return DVar;
978 } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
979 DVar.RefExpr = buildDeclRefExpr(
980 SemaRef, VD, D->getType().getNonReferenceType(),
981 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
982 DVar.CKind = OMPC_threadprivate;
983 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
984 }
985
986 if (isStackEmpty())
987 // Not in OpenMP execution region and top scope was already checked.
988 return DVar;
989
990 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
991 // in a Construct, C/C++, predetermined, p.4]
992 // Static data members are shared.
993 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
994 // in a Construct, C/C++, predetermined, p.7]
995 // Variables with static storage duration that are declared in a scope
996 // inside the construct are shared.
997 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; };
998 if (VD && VD->isStaticDataMember()) {
999 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1000 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1001 return DVar;
1002
1003 DVar.CKind = OMPC_shared;
1004 return DVar;
1005 }
1006
1007 QualType Type = D->getType().getNonReferenceType().getCanonicalType();
1008 bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1009 Type = SemaRef.getASTContext().getBaseElementType(Type);
1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1011 // in a Construct, C/C++, predetermined, p.6]
1012 // Variables with const qualified type having no mutable member are
1013 // shared.
1014 CXXRecordDecl *RD =
1015 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1016 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1017 if (auto *CTD = CTSD->getSpecializedTemplate())
1018 RD = CTD->getTemplatedDecl();
1019 if (IsConstant &&
1020 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1021 RD->hasMutableFields())) {
1022 // Variables with const-qualified type having no mutable member may be
1023 // listed in a firstprivate clause, even if they are static data members.
1024 DSAVarData DVarTemp = hasDSA(
1025 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; },
1026 MatchesAlways, FromParent);
1027 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1028 return DVarTemp;
1029
1030 DVar.CKind = OMPC_shared;
1031 return DVar;
1032 }
1033
1034 // Explicitly specified attributes and local variables with predetermined
1035 // attributes.
1036 auto I = Stack.back().first.rbegin();
1037 auto EndI = Stack.back().first.rend();
1038 if (FromParent && I != EndI)
1039 std::advance(I, 1);
1040 if (I->SharingMap.count(D)) {
1041 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
1042 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
1043 DVar.CKind = I->SharingMap[D].Attributes;
1044 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1045 DVar.DKind = I->Directive;
1046 }
1047
1048 return DVar;
1049}
1050
1051DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1052 bool FromParent) {
1053 if (isStackEmpty()) {
1054 StackTy::reverse_iterator I;
1055 return getDSA(I, D);
1056 }
1057 D = getCanonicalDecl(D);
1058 auto StartI = Stack.back().first.rbegin();
1059 auto EndI = Stack.back().first.rend();
1060 if (FromParent && StartI != EndI)
1061 std::advance(StartI, 1);
1062 return getDSA(StartI, D);
1063}
1064
1065DSAStackTy::DSAVarData
1066DSAStackTy::hasDSA(ValueDecl *D,
1067 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1068 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1069 bool FromParent) {
1070 if (isStackEmpty())
1071 return {};
1072 D = getCanonicalDecl(D);
1073 auto I = Stack.back().first.rbegin();
1074 auto EndI = Stack.back().first.rend();
1075 if (FromParent && I != EndI)
1076 std::advance(I, 1);
1077 for (; I != EndI; std::advance(I, 1)) {
1078 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1079 continue;
1080 auto NewI = I;
1081 DSAVarData DVar = getDSA(NewI, D);
1082 if (I == NewI && CPred(DVar.CKind))
1083 return DVar;
1084 }
1085 return {};
1086}
1087
1088DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1089 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1090 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1091 bool FromParent) {
1092 if (isStackEmpty())
1093 return {};
1094 D = getCanonicalDecl(D);
1095 auto StartI = Stack.back().first.rbegin();
1096 auto EndI = Stack.back().first.rend();
1097 if (FromParent && StartI != EndI)
1098 std::advance(StartI, 1);
1099 if (StartI == EndI || !DPred(StartI->Directive))
1100 return {};
1101 auto NewI = StartI;
1102 DSAVarData DVar = getDSA(NewI, D);
1103 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1104}
1105
1106bool DSAStackTy::hasExplicitDSA(
1107 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1108 unsigned Level, bool NotLastprivate) {
1109 if (isStackEmpty())
1110 return false;
1111 D = getCanonicalDecl(D);
1112 auto StartI = Stack.back().first.begin();
1113 auto EndI = Stack.back().first.end();
1114 if (std::distance(StartI, EndI) <= (int)Level)
1115 return false;
1116 std::advance(StartI, Level);
1117 return (StartI->SharingMap.count(D) > 0) &&
1118 StartI->SharingMap[D].RefExpr.getPointer() &&
1119 CPred(StartI->SharingMap[D].Attributes) &&
1120 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
1121}
1122
1123bool DSAStackTy::hasExplicitDirective(
1124 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1125 unsigned Level) {
1126 if (isStackEmpty())
1127 return false;
1128 auto StartI = Stack.back().first.begin();
1129 auto EndI = Stack.back().first.end();
1130 if (std::distance(StartI, EndI) <= (int)Level)
1131 return false;
1132 std::advance(StartI, Level);
1133 return DPred(StartI->Directive);
1134}
1135
1136bool DSAStackTy::hasDirective(
1137 const llvm::function_ref<bool(OpenMPDirectiveKind,
1138 const DeclarationNameInfo &, SourceLocation)>
1139 &DPred,
1140 bool FromParent) {
1141 // We look only in the enclosing region.
1142 if (isStackEmpty())
1143 return false;
1144 auto StartI = std::next(Stack.back().first.rbegin());
1145 auto EndI = Stack.back().first.rend();
1146 if (FromParent && StartI != EndI)
1147 StartI = std::next(StartI);
1148 for (auto I = StartI, EE = EndI; I != EE; ++I) {
1149 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1150 return true;
1151 }
1152 return false;
1153}
1154
1155void Sema::InitDataSharingAttributesStack() {
1156 VarDataSharingAttributesStack = new DSAStackTy(*this);
1157}
1158
1159#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1160
1161void Sema::pushOpenMPFunctionRegion() {
1162 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1163}
1164
1165void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1166 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1167}
1168
1169bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) {
1170 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1170, __extension__ __PRETTY_FUNCTION__))
;
1171
1172 auto &Ctx = getASTContext();
1173 bool IsByRef = true;
1174
1175 // Find the directive that is associated with the provided scope.
1176 D = cast<ValueDecl>(D->getCanonicalDecl());
1177 auto Ty = D->getType();
1178
1179 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1180 // This table summarizes how a given variable should be passed to the device
1181 // given its type and the clauses where it appears. This table is based on
1182 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1183 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1184 //
1185 // =========================================================================
1186 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1187 // | |(tofrom:scalar)| | pvt | | | |
1188 // =========================================================================
1189 // | scl | | | | - | | bycopy|
1190 // | scl | | - | x | - | - | bycopy|
1191 // | scl | | x | - | - | - | null |
1192 // | scl | x | | | - | | byref |
1193 // | scl | x | - | x | - | - | bycopy|
1194 // | scl | x | x | - | - | - | null |
1195 // | scl | | - | - | - | x | byref |
1196 // | scl | x | - | - | - | x | byref |
1197 //
1198 // | agg | n.a. | | | - | | byref |
1199 // | agg | n.a. | - | x | - | - | byref |
1200 // | agg | n.a. | x | - | - | - | null |
1201 // | agg | n.a. | - | - | - | x | byref |
1202 // | agg | n.a. | - | - | - | x[] | byref |
1203 //
1204 // | ptr | n.a. | | | - | | bycopy|
1205 // | ptr | n.a. | - | x | - | - | bycopy|
1206 // | ptr | n.a. | x | - | - | - | null |
1207 // | ptr | n.a. | - | - | - | x | byref |
1208 // | ptr | n.a. | - | - | - | x[] | bycopy|
1209 // | ptr | n.a. | - | - | x | | bycopy|
1210 // | ptr | n.a. | - | - | x | x | bycopy|
1211 // | ptr | n.a. | - | - | x | x[] | bycopy|
1212 // =========================================================================
1213 // Legend:
1214 // scl - scalar
1215 // ptr - pointer
1216 // agg - aggregate
1217 // x - applies
1218 // - - invalid in this combination
1219 // [] - mapped with an array section
1220 // byref - should be mapped by reference
1221 // byval - should be mapped by value
1222 // null - initialize a local variable to null on the device
1223 //
1224 // Observations:
1225 // - All scalar declarations that show up in a map clause have to be passed
1226 // by reference, because they may have been mapped in the enclosing data
1227 // environment.
1228 // - If the scalar value does not fit the size of uintptr, it has to be
1229 // passed by reference, regardless the result in the table above.
1230 // - For pointers mapped by value that have either an implicit map or an
1231 // array section, the runtime library may pass the NULL value to the
1232 // device instead of the value passed to it by the compiler.
1233
1234 if (Ty->isReferenceType())
1235 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1236
1237 // Locate map clauses and see if the variable being captured is referred to
1238 // in any of those clauses. Here we only care about variables, not fields,
1239 // because fields are part of aggregates.
1240 bool IsVariableUsedInMapClause = false;
1241 bool IsVariableAssociatedWithSection = false;
1242
1243 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1244 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
1245 MapExprComponents,
1246 OpenMPClauseKind WhereFoundClauseKind) {
1247 // Only the map clause information influences how a variable is
1248 // captured. E.g. is_device_ptr does not require changing the default
1249 // behavior.
1250 if (WhereFoundClauseKind != OMPC_map)
1251 return false;
1252
1253 auto EI = MapExprComponents.rbegin();
1254 auto EE = MapExprComponents.rend();
1255
1256 assert(EI != EE && "Invalid map expression!")(static_cast <bool> (EI != EE && "Invalid map expression!"
) ? void (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1256, __extension__ __PRETTY_FUNCTION__))
;
1257
1258 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1259 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1260
1261 ++EI;
1262 if (EI == EE)
1263 return false;
1264
1265 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1266 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1267 isa<MemberExpr>(EI->getAssociatedExpression())) {
1268 IsVariableAssociatedWithSection = true;
1269 // There is nothing more we need to know about this variable.
1270 return true;
1271 }
1272
1273 // Keep looking for more map info.
1274 return false;
1275 });
1276
1277 if (IsVariableUsedInMapClause) {
1278 // If variable is identified in a map clause it is always captured by
1279 // reference except if it is a pointer that is dereferenced somehow.
1280 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1281 } else {
1282 // By default, all the data that has a scalar type is mapped by copy
1283 // (except for reduction variables).
1284 IsByRef =
1285 !Ty->isScalarType() ||
1286 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1287 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1288 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1289 }
1290 }
1291
1292 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1293 IsByRef =
1294 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1295 D,
1296 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1297 Level, /*NotLastprivate=*/true) &&
1298 // If the variable is artificial and must be captured by value - try to
1299 // capture by value.
1300 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1301 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1302 }
1303
1304 // When passing data by copy, we need to make sure it fits the uintptr size
1305 // and alignment, because the runtime library only deals with uintptr types.
1306 // If it does not fit the uintptr size, we need to pass the data by reference
1307 // instead.
1308 if (!IsByRef &&
1309 (Ctx.getTypeSizeInChars(Ty) >
1310 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1311 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1312 IsByRef = true;
1313 }
1314
1315 return IsByRef;
1316}
1317
1318unsigned Sema::getOpenMPNestingLevel() const {
1319 assert(getLangOpts().OpenMP)(static_cast <bool> (getLangOpts().OpenMP) ? void (0) :
__assert_fail ("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1319, __extension__ __PRETTY_FUNCTION__))
;
1320 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
1321}
1322
1323bool Sema::isInOpenMPTargetExecutionDirective() const {
1324 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
1325 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
1326 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
1327 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1328 SourceLocation) -> bool {
1329 return isOpenMPTargetExecutionDirective(K);
1330 },
1331 false);
1332}
1333
1334VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) {
1335 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1335, __extension__ __PRETTY_FUNCTION__))
;
1336 D = getCanonicalDecl(D);
1337
1338 // If we are attempting to capture a global variable in a directive with
1339 // 'target' we return true so that this global is also mapped to the device.
1340 //
1341 // FIXME: If the declaration is enclosed in a 'declare target' directive,
1342 // then it should not be captured. Therefore, an extra check has to be
1343 // inserted here once support for 'declare target' is added.
1344 //
1345 auto *VD = dyn_cast<VarDecl>(D);
1346 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1347 return VD;
1348
1349 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
1350 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
1351 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
1352 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
1353 if (Info.first ||
50
Assuming the condition is false
1354 (VD && VD->hasLocalStorage() &&
1355 isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
1356 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
1357 return VD ? VD : Info.second;
1358 auto DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
51
Within the expansion of the macro 'DSAStack':
a
Null pointer value stored to 'DVarPrivate.PrivateCopy'
1359 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
52
Assuming the condition is true
53
Taking true branch
1360 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
54
'?' condition is false
55
Called C++ object pointer is null
1361 DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
1362 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1363 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
1364 if (DVarPrivate.CKind != OMPC_unknown)
1365 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1366 }
1367 return nullptr;
1368}
1369
1370void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1371 unsigned Level) const {
1372 SmallVector<OpenMPDirectiveKind, 4> Regions;
1373 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
1374 FunctionScopesIndex -= Regions.size();
1375}
1376
1377bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) {
1378 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1378, __extension__ __PRETTY_FUNCTION__))
;
1379 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1380 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1381 Level) ||
1382 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
1383 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
1384 // Consider taskgroup reduction descriptor variable a private to avoid
1385 // possible capture in the region.
1386 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
1387 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1388 Level) &&
1389 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level));
1390}
1391
1392void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) {
1393 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1393, __extension__ __PRETTY_FUNCTION__))
;
1394 D = getCanonicalDecl(D);
1395 OpenMPClauseKind OMPC = OMPC_unknown;
1396 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
1397 const unsigned NewLevel = I - 1;
1398 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
1399 [&OMPC](const OpenMPClauseKind K) {
1400 if (isOpenMPPrivate(K)) {
1401 OMPC = K;
1402 return true;
1403 }
1404 return false;
1405 },
1406 NewLevel))
1407 break;
1408 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1409 D, NewLevel,
1410 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1411 OpenMPClauseKind) { return true; })) {
1412 OMPC = OMPC_map;
1413 break;
1414 }
1415 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1416 NewLevel)) {
1417 OMPC = OMPC_firstprivate;
1418 break;
1419 }
1420 }
1421 if (OMPC != OMPC_unknown)
1422 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1423}
1424
1425bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) {
1426 assert(LangOpts.OpenMP && "OpenMP is not allowed")(static_cast <bool> (LangOpts.OpenMP && "OpenMP is not allowed"
) ? void (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1426, __extension__ __PRETTY_FUNCTION__))
;
1427 // Return true if the current level is no longer enclosed in a target region.
1428
1429 auto *VD = dyn_cast<VarDecl>(D);
1430 return VD && !VD->hasLocalStorage() &&
1431 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1432 Level);
1433}
1434
1435void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
1436
1437void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1438 const DeclarationNameInfo &DirName,
1439 Scope *CurScope, SourceLocation Loc) {
1440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
1441 PushExpressionEvaluationContext(
1442 ExpressionEvaluationContext::PotentiallyEvaluated);
1443}
1444
1445void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1446 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
1447}
1448
1449void Sema::EndOpenMPClause() {
1450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
1451}
1452
1453void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1454 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1455 // A variable of class type (or array thereof) that appears in a lastprivate
1456 // clause requires an accessible, unambiguous default constructor for the
1457 // class type, unless the list item is also specified in a firstprivate
1458 // clause.
1459 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1460 for (auto *C : D->clauses()) {
1461 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1462 SmallVector<Expr *, 8> PrivateCopies;
1463 for (auto *DE : Clause->varlists()) {
1464 if (DE->isValueDependent() || DE->isTypeDependent()) {
1465 PrivateCopies.push_back(nullptr);
1466 continue;
1467 }
1468 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1469 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1470 QualType Type = VD->getType().getNonReferenceType();
1471 auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false);
1472 if (DVar.CKind == OMPC_lastprivate) {
1473 // Generate helper private variable and initialize it with the
1474 // default value. The address of the original variable is replaced
1475 // by the address of the new private variable in CodeGen. This new
1476 // variable is not added to IdResolver, so the code in the OpenMP
1477 // region uses original variable for proper diagnostics.
1478 auto *VDPrivate = buildVarDecl(
1479 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1480 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1481 ActOnUninitializedDecl(VDPrivate);
1482 if (VDPrivate->isInvalidDecl())
1483 continue;
1484 PrivateCopies.push_back(buildDeclRefExpr(
1485 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1486 } else {
1487 // The variable is also a firstprivate, so initialization sequence
1488 // for private copy is generated already.
1489 PrivateCopies.push_back(nullptr);
1490 }
1491 }
1492 // Set initializers to private copies if no errors were found.
1493 if (PrivateCopies.size() == Clause->varlist_size())
1494 Clause->setPrivateCopies(PrivateCopies);
1495 }
1496 }
1497 }
1498
1499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
1500 DiscardCleanupsInEvaluationContext();
1501 PopExpressionEvaluationContext();
1502}
1503
1504static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1505 Expr *NumIterations, Sema &SemaRef,
1506 Scope *S, DSAStackTy *Stack);
1507
1508namespace {
1509
1510class VarDeclFilterCCC : public CorrectionCandidateCallback {
1511private:
1512 Sema &SemaRef;
1513
1514public:
1515 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1516 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1517 NamedDecl *ND = Candidate.getCorrectionDecl();
1518 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1519 return VD->hasGlobalStorage() &&
1520 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1521 SemaRef.getCurScope());
1522 }
1523 return false;
1524 }
1525};
1526
1527class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1528private:
1529 Sema &SemaRef;
1530
1531public:
1532 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1533 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1534 NamedDecl *ND = Candidate.getCorrectionDecl();
1535 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1536 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1537 SemaRef.getCurScope());
1538 }
1539 return false;
1540 }
1541};
1542
1543} // namespace
1544
1545ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1546 CXXScopeSpec &ScopeSpec,
1547 const DeclarationNameInfo &Id) {
1548 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1549 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1550
1551 if (Lookup.isAmbiguous())
1552 return ExprError();
1553
1554 VarDecl *VD;
1555 if (!Lookup.isSingleResult()) {
1556 if (TypoCorrection Corrected = CorrectTypo(
1557 Id, LookupOrdinaryName, CurScope, nullptr,
1558 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1559 diagnoseTypo(Corrected,
1560 PDiag(Lookup.empty()
1561 ? diag::err_undeclared_var_use_suggest
1562 : diag::err_omp_expected_var_arg_suggest)
1563 << Id.getName());
1564 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1565 } else {
1566 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1567 : diag::err_omp_expected_var_arg)
1568 << Id.getName();
1569 return ExprError();
1570 }
1571 } else {
1572 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1573 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1574 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1575 return ExprError();
1576 }
1577 }
1578 Lookup.suppressDiagnostics();
1579
1580 // OpenMP [2.9.2, Syntax, C/C++]
1581 // Variables must be file-scope, namespace-scope, or static block-scope.
1582 if (!VD->hasGlobalStorage()) {
1583 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1584 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1585 bool IsDecl =
1586 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1587 Diag(VD->getLocation(),
1588 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1589 << VD;
1590 return ExprError();
1591 }
1592
1593 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1594 NamedDecl *ND = CanonicalVD;
1595 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1596 // A threadprivate directive for file-scope variables must appear outside
1597 // any definition or declaration.
1598 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1599 !getCurLexicalContext()->isTranslationUnit()) {
1600 Diag(Id.getLoc(), diag::err_omp_var_scope)
1601 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1602 bool IsDecl =
1603 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1604 Diag(VD->getLocation(),
1605 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1606 << VD;
1607 return ExprError();
1608 }
1609 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1610 // A threadprivate directive for static class member variables must appear
1611 // in the class definition, in the same scope in which the member
1612 // variables are declared.
1613 if (CanonicalVD->isStaticDataMember() &&
1614 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1615 Diag(Id.getLoc(), diag::err_omp_var_scope)
1616 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1617 bool IsDecl =
1618 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1619 Diag(VD->getLocation(),
1620 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1621 << VD;
1622 return ExprError();
1623 }
1624 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1625 // A threadprivate directive for namespace-scope variables must appear
1626 // outside any definition or declaration other than the namespace
1627 // definition itself.
1628 if (CanonicalVD->getDeclContext()->isNamespace() &&
1629 (!getCurLexicalContext()->isFileContext() ||
1630 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1631 Diag(Id.getLoc(), diag::err_omp_var_scope)
1632 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1633 bool IsDecl =
1634 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1635 Diag(VD->getLocation(),
1636 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1637 << VD;
1638 return ExprError();
1639 }
1640 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1641 // A threadprivate directive for static block-scope variables must appear
1642 // in the scope of the variable and not in a nested scope.
1643 if (CanonicalVD->isStaticLocal() && CurScope &&
1644 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1645 Diag(Id.getLoc(), diag::err_omp_var_scope)
1646 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1647 bool IsDecl =
1648 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1649 Diag(VD->getLocation(),
1650 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1651 << VD;
1652 return ExprError();
1653 }
1654
1655 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1656 // A threadprivate directive must lexically precede all references to any
1657 // of the variables in its list.
1658 if (VD->isUsed() && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
1659 Diag(Id.getLoc(), diag::err_omp_var_used)
1660 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1661 return ExprError();
1662 }
1663
1664 QualType ExprType = VD->getType().getNonReferenceType();
1665 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1666 SourceLocation(), VD,
1667 /*RefersToEnclosingVariableOrCapture=*/false,
1668 Id.getLoc(), ExprType, VK_LValue);
1669}
1670
1671Sema::DeclGroupPtrTy
1672Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1673 ArrayRef<Expr *> VarList) {
1674 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1675 CurContext->addDecl(D);
1676 return DeclGroupPtrTy::make(DeclGroupRef(D));
1677 }
1678 return nullptr;
1679}
1680
1681namespace {
1682class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1683 Sema &SemaRef;
1684
1685public:
1686 bool VisitDeclRefExpr(const DeclRefExpr *E) {
1687 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1688 if (VD->hasLocalStorage()) {
1689 SemaRef.Diag(E->getLocStart(),
1690 diag::err_omp_local_var_in_threadprivate_init)
1691 << E->getSourceRange();
1692 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1693 << VD << VD->getSourceRange();
1694 return true;
1695 }
1696 }
1697 return false;
1698 }
1699 bool VisitStmt(const Stmt *S) {
1700 for (auto Child : S->children()) {
1701 if (Child && Visit(Child))
1702 return true;
1703 }
1704 return false;
1705 }
1706 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1707};
1708} // namespace
1709
1710OMPThreadPrivateDecl *
1711Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1712 SmallVector<Expr *, 8> Vars;
1713 for (auto &RefExpr : VarList) {
1714 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1715 VarDecl *VD = cast<VarDecl>(DE->getDecl());
1716 SourceLocation ILoc = DE->getExprLoc();
1717
1718 // Mark variable as used.
1719 VD->setReferenced();
1720 VD->markUsed(Context);
1721
1722 QualType QType = VD->getType();
1723 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1724 // It will be analyzed later.
1725 Vars.push_back(DE);
1726 continue;
1727 }
1728
1729 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1730 // A threadprivate variable must not have an incomplete type.
1731 if (RequireCompleteType(ILoc, VD->getType(),
1732 diag::err_omp_threadprivate_incomplete_type)) {
1733 continue;
1734 }
1735
1736 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1737 // A threadprivate variable must not have a reference type.
1738 if (VD->getType()->isReferenceType()) {
1739 Diag(ILoc, diag::err_omp_ref_type_arg)
1740 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1741 bool IsDecl =
1742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1743 Diag(VD->getLocation(),
1744 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1745 << VD;
1746 continue;
1747 }
1748
1749 // Check if this is a TLS variable. If TLS is not being supported, produce
1750 // the corresponding diagnostic.
1751 if ((VD->getTLSKind() != VarDecl::TLS_None &&
1752 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1753 getLangOpts().OpenMPUseTLS &&
1754 getASTContext().getTargetInfo().isTLSSupported())) ||
1755 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1756 !VD->isLocalVarDecl())) {
1757 Diag(ILoc, diag::err_omp_var_thread_local)
1758 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1759 bool IsDecl =
1760 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1761 Diag(VD->getLocation(),
1762 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1763 << VD;
1764 continue;
1765 }
1766
1767 // Check if initial value of threadprivate variable reference variable with
1768 // local storage (it is not supported by runtime).
1769 if (auto Init = VD->getAnyInitializer()) {
1770 LocalVarRefChecker Checker(*this);
1771 if (Checker.Visit(Init))
1772 continue;
1773 }
1774
1775 Vars.push_back(RefExpr);
1776 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
1777 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1778 Context, SourceRange(Loc, Loc)));
1779 if (auto *ML = Context.getASTMutationListener())
1780 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1781 }
1782 OMPThreadPrivateDecl *D = nullptr;
1783 if (!Vars.empty()) {
1784 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1785 Vars);
1786 D->setAccess(AS_public);
1787 }
1788 return D;
1789}
1790
1791static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1792 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1793 bool IsLoopIterVar = false) {
1794 if (DVar.RefExpr) {
1795 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1796 << getOpenMPClauseName(DVar.CKind);
1797 return;
1798 }
1799 enum {
1800 PDSA_StaticMemberShared,
1801 PDSA_StaticLocalVarShared,
1802 PDSA_LoopIterVarPrivate,
1803 PDSA_LoopIterVarLinear,
1804 PDSA_LoopIterVarLastprivate,
1805 PDSA_ConstVarShared,
1806 PDSA_GlobalVarShared,
1807 PDSA_TaskVarFirstprivate,
1808 PDSA_LocalVarPrivate,
1809 PDSA_Implicit
1810 } Reason = PDSA_Implicit;
1811 bool ReportHint = false;
1812 auto ReportLoc = D->getLocation();
1813 auto *VD = dyn_cast<VarDecl>(D);
1814 if (IsLoopIterVar) {
1815 if (DVar.CKind == OMPC_private)
1816 Reason = PDSA_LoopIterVarPrivate;
1817 else if (DVar.CKind == OMPC_lastprivate)
1818 Reason = PDSA_LoopIterVarLastprivate;
1819 else
1820 Reason = PDSA_LoopIterVarLinear;
1821 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1822 DVar.CKind == OMPC_firstprivate) {
1823 Reason = PDSA_TaskVarFirstprivate;
1824 ReportLoc = DVar.ImplicitDSALoc;
1825 } else if (VD && VD->isStaticLocal())
1826 Reason = PDSA_StaticLocalVarShared;
1827 else if (VD && VD->isStaticDataMember())
1828 Reason = PDSA_StaticMemberShared;
1829 else if (VD && VD->isFileVarDecl())
1830 Reason = PDSA_GlobalVarShared;
1831 else if (D->getType().isConstant(SemaRef.getASTContext()))
1832 Reason = PDSA_ConstVarShared;
1833 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1834 ReportHint = true;
1835 Reason = PDSA_LocalVarPrivate;
1836 }
1837 if (Reason != PDSA_Implicit) {
1838 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1839 << Reason << ReportHint
1840 << getOpenMPDirectiveName(Stack->getCurrentDirective());
1841 } else if (DVar.ImplicitDSALoc.isValid()) {
1842 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1843 << getOpenMPClauseName(DVar.CKind);
1844 }
1845}
1846
1847namespace {
1848class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1849 DSAStackTy *Stack;
1850 Sema &SemaRef;
1851 bool ErrorFound;
1852 CapturedStmt *CS;
1853 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1854 llvm::SmallVector<Expr *, 8> ImplicitMap;
1855 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1856 llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1857
1858public:
1859 void VisitDeclRefExpr(DeclRefExpr *E) {
1860 if (E->isTypeDependent() || E->isValueDependent() ||
1861 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1862 return;
1863 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1864 VD = VD->getCanonicalDecl();
1865 // Skip internally declared variables.
1866 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1867 return;
1868
1869 auto DVar = Stack->getTopDSA(VD, false);
1870 // Check if the variable has explicit DSA set and stop analysis if it so.
1871 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1872 return;
1873
1874 // Skip internally declared static variables.
1875 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1876 return;
1877
1878 auto ELoc = E->getExprLoc();
1879 auto DKind = Stack->getCurrentDirective();
1880 // The default(none) clause requires that each variable that is referenced
1881 // in the construct, and does not have a predetermined data-sharing
1882 // attribute, must have its data-sharing attribute explicitly determined
1883 // by being listed in a data-sharing attribute clause.
1884 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1885 isParallelOrTaskRegion(DKind) &&
1886 VarsWithInheritedDSA.count(VD) == 0) {
1887 VarsWithInheritedDSA[VD] = E;
1888 return;
1889 }
1890
1891 if (isOpenMPTargetExecutionDirective(DKind) &&
1892 !Stack->isLoopControlVariable(VD).first) {
1893 if (!Stack->checkMappableExprComponentListsForDecl(
1894 VD, /*CurrentRegionOnly=*/true,
1895 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1896 StackComponents,
1897 OpenMPClauseKind) {
1898 // Variable is used if it has been marked as an array, array
1899 // section or the variable iself.
1900 return StackComponents.size() == 1 ||
1901 std::all_of(
1902 std::next(StackComponents.rbegin()),
1903 StackComponents.rend(),
1904 [](const OMPClauseMappableExprCommon::
1905 MappableComponent &MC) {
1906 return MC.getAssociatedDeclaration() ==
1907 nullptr &&
1908 (isa<OMPArraySectionExpr>(
1909 MC.getAssociatedExpression()) ||
1910 isa<ArraySubscriptExpr>(
1911 MC.getAssociatedExpression()));
1912 });
1913 })) {
1914 bool IsFirstprivate = false;
1915 // By default lambdas are captured as firstprivates.
1916 if (const auto *RD =
1917 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1918 IsFirstprivate = RD->isLambda();
1919 IsFirstprivate =
1920 IsFirstprivate ||
1921 (VD->getType().getNonReferenceType()->isScalarType() &&
1922 Stack->getDefaultDMA() != DMA_tofrom_scalar);
1923 if (IsFirstprivate)
1924 ImplicitFirstprivate.emplace_back(E);
1925 else
1926 ImplicitMap.emplace_back(E);
1927 return;
1928 }
1929 }
1930
1931 // OpenMP [2.9.3.6, Restrictions, p.2]
1932 // A list item that appears in a reduction clause of the innermost
1933 // enclosing worksharing or parallel construct may not be accessed in an
1934 // explicit task.
1935 DVar = Stack->hasInnermostDSA(
1936 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1937 [](OpenMPDirectiveKind K) -> bool {
1938 return isOpenMPParallelDirective(K) ||
1939 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1940 },
1941 /*FromParent=*/true);
1942 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1943 ErrorFound = true;
1944 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1945 ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1946 return;
1947 }
1948
1949 // Define implicit data-sharing attributes for task.
1950 DVar = Stack->getImplicitDSA(VD, false);
1951 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1952 !Stack->isLoopControlVariable(VD).first)
1953 ImplicitFirstprivate.push_back(E);
1954 }
1955 }
1956 void VisitMemberExpr(MemberExpr *E) {
1957 if (E->isTypeDependent() || E->isValueDependent() ||
1958 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1959 return;
1960 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1961 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1962 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1963 if (!FD)
1964 return;
1965 auto DVar = Stack->getTopDSA(FD, false);
1966 // Check if the variable has explicit DSA set and stop analysis if it
1967 // so.
1968 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1969 return;
1970
1971 if (isOpenMPTargetExecutionDirective(DKind) &&
1972 !Stack->isLoopControlVariable(FD).first &&
1973 !Stack->checkMappableExprComponentListsForDecl(
1974 FD, /*CurrentRegionOnly=*/true,
1975 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1976 StackComponents,
1977 OpenMPClauseKind) {
1978 return isa<CXXThisExpr>(
1979 cast<MemberExpr>(
1980 StackComponents.back().getAssociatedExpression())
1981 ->getBase()
1982 ->IgnoreParens());
1983 })) {
1984 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1985 // A bit-field cannot appear in a map clause.
1986 //
1987 if (FD->isBitField())
1988 return;
1989 ImplicitMap.emplace_back(E);
1990 return;
1991 }
1992
1993 auto ELoc = E->getExprLoc();
1994 // OpenMP [2.9.3.6, Restrictions, p.2]
1995 // A list item that appears in a reduction clause of the innermost
1996 // enclosing worksharing or parallel construct may not be accessed in
1997 // an explicit task.
1998 DVar = Stack->hasInnermostDSA(
1999 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
2000 [](OpenMPDirectiveKind K) -> bool {
2001 return isOpenMPParallelDirective(K) ||
2002 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2003 },
2004 /*FromParent=*/true);
2005 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2006 ErrorFound = true;
2007 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2008 ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2009 return;
2010 }
2011
2012 // Define implicit data-sharing attributes for task.
2013 DVar = Stack->getImplicitDSA(FD, false);
2014 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2015 !Stack->isLoopControlVariable(FD).first)
2016 ImplicitFirstprivate.push_back(E);
2017 return;
2018 }
2019 if (isOpenMPTargetExecutionDirective(DKind)) {
2020 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2021 if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2022 /*NoDiagnose=*/true))
2023 return;
2024 auto *VD = cast<ValueDecl>(
2025 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2026 if (!Stack->checkMappableExprComponentListsForDecl(
2027 VD, /*CurrentRegionOnly=*/true,
2028 [&CurComponents](
2029 OMPClauseMappableExprCommon::MappableExprComponentListRef
2030 StackComponents,
2031 OpenMPClauseKind) {
2032 auto CCI = CurComponents.rbegin();
2033 auto CCE = CurComponents.rend();
2034 for (const auto &SC : llvm::reverse(StackComponents)) {
2035 // Do both expressions have the same kind?
2036 if (CCI->getAssociatedExpression()->getStmtClass() !=
2037 SC.getAssociatedExpression()->getStmtClass())
2038 if (!(isa<OMPArraySectionExpr>(
2039 SC.getAssociatedExpression()) &&
2040 isa<ArraySubscriptExpr>(
2041 CCI->getAssociatedExpression())))
2042 return false;
2043
2044 Decl *CCD = CCI->getAssociatedDeclaration();
2045 Decl *SCD = SC.getAssociatedDeclaration();
2046 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2047 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2048 if (SCD != CCD)
2049 return false;
2050 std::advance(CCI, 1);
2051 if (CCI == CCE)
2052 break;
2053 }
2054 return true;
2055 })) {
2056 Visit(E->getBase());
2057 }
2058 } else
2059 Visit(E->getBase());
2060 }
2061 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2062 for (auto *C : S->clauses()) {
2063 // Skip analysis of arguments of implicitly defined firstprivate clause
2064 // for task|target directives.
2065 // Skip analysis of arguments of implicitly defined map clause for target
2066 // directives.
2067 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2068 C->isImplicit())) {
2069 for (auto *CC : C->children()) {
2070 if (CC)
2071 Visit(CC);
2072 }
2073 }
2074 }
2075 }
2076 void VisitStmt(Stmt *S) {
2077 for (auto *C : S->children()) {
2078 if (C && !isa<OMPExecutableDirective>(C))
2079 Visit(C);
2080 }
2081 }
2082
2083 bool isErrorFound() { return ErrorFound; }
2084 ArrayRef<Expr *> getImplicitFirstprivate() const {
2085 return ImplicitFirstprivate;
2086 }
2087 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2088 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2089 return VarsWithInheritedDSA;
2090 }
2091
2092 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2093 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2094};
2095} // namespace
2096
2097void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2098 switch (DKind) {
2099 case OMPD_parallel:
2100 case OMPD_parallel_for:
2101 case OMPD_parallel_for_simd:
2102 case OMPD_parallel_sections:
2103 case OMPD_teams:
2104 case OMPD_teams_distribute:
2105 case OMPD_teams_distribute_simd: {
2106 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2107 QualType KmpInt32PtrTy =
2108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2109 Sema::CapturedParamNameType Params[] = {
2110 std::make_pair(".global_tid.", KmpInt32PtrTy),
2111 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2112 std::make_pair(StringRef(), QualType()) // __context with shared vars
2113 };
2114 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2115 Params);
2116 break;
2117 }
2118 case OMPD_target_teams:
2119 case OMPD_target_parallel:
2120 case OMPD_target_parallel_for:
2121 case OMPD_target_parallel_for_simd:
2122 case OMPD_target_teams_distribute:
2123 case OMPD_target_teams_distribute_simd: {
2124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2125 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2126 FunctionProtoType::ExtProtoInfo EPI;
2127 EPI.Variadic = true;
2128 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2129 Sema::CapturedParamNameType Params[] = {
2130 std::make_pair(".global_tid.", KmpInt32Ty),
2131 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2132 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2133 std::make_pair(".copy_fn.",
2134 Context.getPointerType(CopyFnType).withConst()),
2135 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2136 std::make_pair(StringRef(), QualType()) // __context with shared vars
2137 };
2138 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2139 Params);
2140 // Mark this captured region as inlined, because we don't use outlined
2141 // function directly.
2142 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2143 AlwaysInlineAttr::CreateImplicit(
2144 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2145 Sema::CapturedParamNameType ParamsTarget[] = {
2146 std::make_pair(StringRef(), QualType()) // __context with shared vars
2147 };
2148 // Start a captured region for 'target' with no implicit parameters.
2149 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2150 ParamsTarget);
2151 QualType KmpInt32PtrTy =
2152 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2153 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2154 std::make_pair(".global_tid.", KmpInt32PtrTy),
2155 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2156 std::make_pair(StringRef(), QualType()) // __context with shared vars
2157 };
2158 // Start a captured region for 'teams' or 'parallel'. Both regions have
2159 // the same implicit parameters.
2160 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2161 ParamsTeamsOrParallel);
2162 break;
2163 }
2164 case OMPD_target:
2165 case OMPD_target_simd: {
2166 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2167 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2168 FunctionProtoType::ExtProtoInfo EPI;
2169 EPI.Variadic = true;
2170 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2171 Sema::CapturedParamNameType Params[] = {
2172 std::make_pair(".global_tid.", KmpInt32Ty),
2173 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2174 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2175 std::make_pair(".copy_fn.",
2176 Context.getPointerType(CopyFnType).withConst()),
2177 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2178 std::make_pair(StringRef(), QualType()) // __context with shared vars
2179 };
2180 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2181 Params);
2182 // Mark this captured region as inlined, because we don't use outlined
2183 // function directly.
2184 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2185 AlwaysInlineAttr::CreateImplicit(
2186 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2187 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2188 std::make_pair(StringRef(), QualType()));
2189 break;
2190 }
2191 case OMPD_simd:
2192 case OMPD_for:
2193 case OMPD_for_simd:
2194 case OMPD_sections:
2195 case OMPD_section:
2196 case OMPD_single:
2197 case OMPD_master:
2198 case OMPD_critical:
2199 case OMPD_taskgroup:
2200 case OMPD_distribute:
2201 case OMPD_distribute_simd:
2202 case OMPD_ordered:
2203 case OMPD_atomic:
2204 case OMPD_target_data: {
2205 Sema::CapturedParamNameType Params[] = {
2206 std::make_pair(StringRef(), QualType()) // __context with shared vars
2207 };
2208 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2209 Params);
2210 break;
2211 }
2212 case OMPD_task: {
2213 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2214 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2215 FunctionProtoType::ExtProtoInfo EPI;
2216 EPI.Variadic = true;
2217 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2218 Sema::CapturedParamNameType Params[] = {
2219 std::make_pair(".global_tid.", KmpInt32Ty),
2220 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2221 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2222 std::make_pair(".copy_fn.",
2223 Context.getPointerType(CopyFnType).withConst()),
2224 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2225 std::make_pair(StringRef(), QualType()) // __context with shared vars
2226 };
2227 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2228 Params);
2229 // Mark this captured region as inlined, because we don't use outlined
2230 // function directly.
2231 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2232 AlwaysInlineAttr::CreateImplicit(
2233 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2234 break;
2235 }
2236 case OMPD_taskloop:
2237 case OMPD_taskloop_simd: {
2238 QualType KmpInt32Ty =
2239 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2240 QualType KmpUInt64Ty =
2241 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2242 QualType KmpInt64Ty =
2243 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2244 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2245 FunctionProtoType::ExtProtoInfo EPI;
2246 EPI.Variadic = true;
2247 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2248 Sema::CapturedParamNameType Params[] = {
2249 std::make_pair(".global_tid.", KmpInt32Ty),
2250 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2251 std::make_pair(".privates.",
2252 Context.VoidPtrTy.withConst().withRestrict()),
2253 std::make_pair(
2254 ".copy_fn.",
2255 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2256 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2257 std::make_pair(".lb.", KmpUInt64Ty),
2258 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2259 std::make_pair(".liter.", KmpInt32Ty),
2260 std::make_pair(".reductions.",
2261 Context.VoidPtrTy.withConst().withRestrict()),
2262 std::make_pair(StringRef(), QualType()) // __context with shared vars
2263 };
2264 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2265 Params);
2266 // Mark this captured region as inlined, because we don't use outlined
2267 // function directly.
2268 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2269 AlwaysInlineAttr::CreateImplicit(
2270 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2271 break;
2272 }
2273 case OMPD_distribute_parallel_for_simd:
2274 case OMPD_distribute_parallel_for: {
2275 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2276 QualType KmpInt32PtrTy =
2277 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2278 Sema::CapturedParamNameType Params[] = {
2279 std::make_pair(".global_tid.", KmpInt32PtrTy),
2280 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2281 std::make_pair(".previous.lb.", Context.getSizeType()),
2282 std::make_pair(".previous.ub.", Context.getSizeType()),
2283 std::make_pair(StringRef(), QualType()) // __context with shared vars
2284 };
2285 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2286 Params);
2287 break;
2288 }
2289 case OMPD_target_teams_distribute_parallel_for:
2290 case OMPD_target_teams_distribute_parallel_for_simd: {
2291 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2292 QualType KmpInt32PtrTy =
2293 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2294
2295 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2296 FunctionProtoType::ExtProtoInfo EPI;
2297 EPI.Variadic = true;
2298 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2299 Sema::CapturedParamNameType Params[] = {
2300 std::make_pair(".global_tid.", KmpInt32Ty),
2301 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2302 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2303 std::make_pair(".copy_fn.",
2304 Context.getPointerType(CopyFnType).withConst()),
2305 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2306 std::make_pair(StringRef(), QualType()) // __context with shared vars
2307 };
2308 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2309 Params);
2310 // Mark this captured region as inlined, because we don't use outlined
2311 // function directly.
2312 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2313 AlwaysInlineAttr::CreateImplicit(
2314 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2315 Sema::CapturedParamNameType ParamsTarget[] = {
2316 std::make_pair(StringRef(), QualType()) // __context with shared vars
2317 };
2318 // Start a captured region for 'target' with no implicit parameters.
2319 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2320 ParamsTarget);
2321
2322 Sema::CapturedParamNameType ParamsTeams[] = {
2323 std::make_pair(".global_tid.", KmpInt32PtrTy),
2324 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2325 std::make_pair(StringRef(), QualType()) // __context with shared vars
2326 };
2327 // Start a captured region for 'target' with no implicit parameters.
2328 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2329 ParamsTeams);
2330
2331 Sema::CapturedParamNameType ParamsParallel[] = {
2332 std::make_pair(".global_tid.", KmpInt32PtrTy),
2333 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2334 std::make_pair(".previous.lb.", Context.getSizeType()),
2335 std::make_pair(".previous.ub.", Context.getSizeType()),
2336 std::make_pair(StringRef(), QualType()) // __context with shared vars
2337 };
2338 // Start a captured region for 'teams' or 'parallel'. Both regions have
2339 // the same implicit parameters.
2340 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2341 ParamsParallel);
2342 break;
2343 }
2344
2345 case OMPD_teams_distribute_parallel_for:
2346 case OMPD_teams_distribute_parallel_for_simd: {
2347 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2348 QualType KmpInt32PtrTy =
2349 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2350
2351 Sema::CapturedParamNameType ParamsTeams[] = {
2352 std::make_pair(".global_tid.", KmpInt32PtrTy),
2353 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2354 std::make_pair(StringRef(), QualType()) // __context with shared vars
2355 };
2356 // Start a captured region for 'target' with no implicit parameters.
2357 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2358 ParamsTeams);
2359
2360 Sema::CapturedParamNameType ParamsParallel[] = {
2361 std::make_pair(".global_tid.", KmpInt32PtrTy),
2362 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2363 std::make_pair(".previous.lb.", Context.getSizeType()),
2364 std::make_pair(".previous.ub.", Context.getSizeType()),
2365 std::make_pair(StringRef(), QualType()) // __context with shared vars
2366 };
2367 // Start a captured region for 'teams' or 'parallel'. Both regions have
2368 // the same implicit parameters.
2369 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2370 ParamsParallel);
2371 break;
2372 }
2373 case OMPD_target_update:
2374 case OMPD_target_enter_data:
2375 case OMPD_target_exit_data: {
2376 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2377 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2378 FunctionProtoType::ExtProtoInfo EPI;
2379 EPI.Variadic = true;
2380 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2381 Sema::CapturedParamNameType Params[] = {
2382 std::make_pair(".global_tid.", KmpInt32Ty),
2383 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2384 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2385 std::make_pair(".copy_fn.",
2386 Context.getPointerType(CopyFnType).withConst()),
2387 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2388 std::make_pair(StringRef(), QualType()) // __context with shared vars
2389 };
2390 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2391 Params);
2392 // Mark this captured region as inlined, because we don't use outlined
2393 // function directly.
2394 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2395 AlwaysInlineAttr::CreateImplicit(
2396 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2397 break;
2398 }
2399 case OMPD_threadprivate:
2400 case OMPD_taskyield:
2401 case OMPD_barrier:
2402 case OMPD_taskwait:
2403 case OMPD_cancellation_point:
2404 case OMPD_cancel:
2405 case OMPD_flush:
2406 case OMPD_declare_reduction:
2407 case OMPD_declare_simd:
2408 case OMPD_declare_target:
2409 case OMPD_end_declare_target:
2410 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2410)
;
2411 case OMPD_unknown:
2412 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2412)
;
2413 }
2414}
2415
2416int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2417 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2418 getOpenMPCaptureRegions(CaptureRegions, DKind);
2419 return CaptureRegions.size();
2420}
2421
2422static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2423 Expr *CaptureExpr, bool WithInit,
2424 bool AsExpression) {
2425 assert(CaptureExpr)(static_cast <bool> (CaptureExpr) ? void (0) : __assert_fail
("CaptureExpr", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2425, __extension__ __PRETTY_FUNCTION__))
;
2426 ASTContext &C = S.getASTContext();
2427 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2428 QualType Ty = Init->getType();
2429 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2430 if (S.getLangOpts().CPlusPlus) {
2431 Ty = C.getLValueReferenceType(Ty);
2432 } else {
2433 Ty = C.getPointerType(Ty);
2434 ExprResult Res =
2435 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2436 if (!Res.isUsable())
2437 return nullptr;
2438 Init = Res.get();
2439 }
2440 WithInit = true;
2441 }
2442 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2443 CaptureExpr->getLocStart());
2444 if (!WithInit)
2445 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2446 S.CurContext->addHiddenDecl(CED);
2447 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2448 return CED;
2449}
2450
2451static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2452 bool WithInit) {
2453 OMPCapturedExprDecl *CD;
2454 if (auto *VD = S.IsOpenMPCapturedDecl(D)) {
49
Calling 'Sema::IsOpenMPCapturedDecl'
2455 CD = cast<OMPCapturedExprDecl>(VD);
2456 } else {
2457 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2458 /*AsExpression=*/false);
2459 }
2460 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2461 CaptureExpr->getExprLoc());
2462}
2463
2464static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2465 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2466 if (!Ref) {
2467 OMPCapturedExprDecl *CD = buildCaptureDecl(
2468 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2469 /*WithInit=*/true, /*AsExpression=*/true);
2470 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2471 CaptureExpr->getExprLoc());
2472 }
2473 ExprResult Res = Ref;
2474 if (!S.getLangOpts().CPlusPlus &&
2475 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2476 Ref->getType()->isPointerType()) {
2477 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2478 if (!Res.isUsable())
2479 return ExprError();
2480 }
2481 return S.DefaultLvalueConversion(Res.get());
2482}
2483
2484namespace {
2485// OpenMP directives parsed in this section are represented as a
2486// CapturedStatement with an associated statement. If a syntax error
2487// is detected during the parsing of the associated statement, the
2488// compiler must abort processing and close the CapturedStatement.
2489//
2490// Combined directives such as 'target parallel' have more than one
2491// nested CapturedStatements. This RAII ensures that we unwind out
2492// of all the nested CapturedStatements when an error is found.
2493class CaptureRegionUnwinderRAII {
2494private:
2495 Sema &S;
2496 bool &ErrorFound;
2497 OpenMPDirectiveKind DKind;
2498
2499public:
2500 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2501 OpenMPDirectiveKind DKind)
2502 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2503 ~CaptureRegionUnwinderRAII() {
2504 if (ErrorFound) {
2505 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2506 while (--ThisCaptureLevel >= 0)
2507 S.ActOnCapturedRegionError();
2508 }
2509 }
2510};
2511} // namespace
2512
2513StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2514 ArrayRef<OMPClause *> Clauses) {
2515 bool ErrorFound = false;
2516 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2517 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2518 if (!S.isUsable()) {
2519 ErrorFound = true;
2520 return StmtError();
2521 }
2522
2523 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2524 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2525 OMPOrderedClause *OC = nullptr;
2526 OMPScheduleClause *SC = nullptr;
2527 SmallVector<OMPLinearClause *, 4> LCs;
2528 SmallVector<OMPClauseWithPreInit *, 8> PICs;
2529 // This is required for proper codegen.
2530 for (auto *Clause : Clauses) {
2531 if (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2532 Clause->getClauseKind() == OMPC_in_reduction) {
2533 // Capture taskgroup task_reduction descriptors inside the tasking regions
2534 // with the corresponding in_reduction items.
2535 auto *IRC = cast<OMPInReductionClause>(Clause);
2536 for (auto *E : IRC->taskgroup_descriptors())
2537 if (E)
2538 MarkDeclarationsReferencedInExpr(E);
2539 }
2540 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2541 Clause->getClauseKind() == OMPC_copyprivate ||
2542 (getLangOpts().OpenMPUseTLS &&
2543 getASTContext().getTargetInfo().isTLSSupported() &&
2544 Clause->getClauseKind() == OMPC_copyin)) {
2545 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2546 // Mark all variables in private list clauses as used in inner region.
2547 for (auto *VarRef : Clause->children()) {
2548 if (auto *E = cast_or_null<Expr>(VarRef)) {
2549 MarkDeclarationsReferencedInExpr(E);
2550 }
2551 }
2552 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
2553 } else if (CaptureRegions.size() > 1 ||
2554 CaptureRegions.back() != OMPD_unknown) {
2555 if (auto *C = OMPClauseWithPreInit::get(Clause))
2556 PICs.push_back(C);
2557 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2558 if (auto *E = C->getPostUpdateExpr())
2559 MarkDeclarationsReferencedInExpr(E);
2560 }
2561 }
2562 if (Clause->getClauseKind() == OMPC_schedule)
2563 SC = cast<OMPScheduleClause>(Clause);
2564 else if (Clause->getClauseKind() == OMPC_ordered)
2565 OC = cast<OMPOrderedClause>(Clause);
2566 else if (Clause->getClauseKind() == OMPC_linear)
2567 LCs.push_back(cast<OMPLinearClause>(Clause));
2568 }
2569 // OpenMP, 2.7.1 Loop Construct, Restrictions
2570 // The nonmonotonic modifier cannot be specified if an ordered clause is
2571 // specified.
2572 if (SC &&
2573 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2574 SC->getSecondScheduleModifier() ==
2575 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2576 OC) {
2577 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2578 ? SC->getFirstScheduleModifierLoc()
2579 : SC->getSecondScheduleModifierLoc(),
2580 diag::err_omp_schedule_nonmonotonic_ordered)
2581 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2582 ErrorFound = true;
2583 }
2584 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2585 for (auto *C : LCs) {
2586 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2587 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2588 }
2589 ErrorFound = true;
2590 }
2591 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2592 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
2593 OC->getNumForLoops()) {
2594 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2595 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2596 ErrorFound = true;
2597 }
2598 if (ErrorFound) {
2599 return StmtError();
2600 }
2601 StmtResult SR = S;
2602 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2603 // Mark all variables in private list clauses as used in inner region.
2604 // Required for proper codegen of combined directives.
2605 // TODO: add processing for other clauses.
2606 if (ThisCaptureRegion != OMPD_unknown) {
2607 for (auto *C : PICs) {
2608 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2609 // Find the particular capture region for the clause if the
2610 // directive is a combined one with multiple capture regions.
2611 // If the directive is not a combined one, the capture region
2612 // associated with the clause is OMPD_unknown and is generated
2613 // only once.
2614 if (CaptureRegion == ThisCaptureRegion ||
2615 CaptureRegion == OMPD_unknown) {
2616 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2617 for (auto *D : DS->decls())
2618 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2619 }
2620 }
2621 }
2622 }
2623 SR = ActOnCapturedRegionEnd(SR.get());
2624 }
2625 return SR;
2626}
2627
2628static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2629 OpenMPDirectiveKind CancelRegion,
2630 SourceLocation StartLoc) {
2631 // CancelRegion is only needed for cancel and cancellation_point.
2632 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2633 return false;
2634
2635 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2636 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2637 return false;
2638
2639 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2640 << getOpenMPDirectiveName(CancelRegion);
2641 return true;
2642}
2643
2644static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2645 OpenMPDirectiveKind CurrentRegion,
2646 const DeclarationNameInfo &CurrentName,
2647 OpenMPDirectiveKind CancelRegion,
2648 SourceLocation StartLoc) {
2649 if (Stack->getCurScope()) {
2650 auto ParentRegion = Stack->getParentDirective();
2651 auto OffendingRegion = ParentRegion;
2652 bool NestingProhibited = false;
2653 bool CloseNesting = true;
2654 bool OrphanSeen = false;
2655 enum {
2656 NoRecommend,
2657 ShouldBeInParallelRegion,
2658 ShouldBeInOrderedRegion,
2659 ShouldBeInTargetRegion,
2660 ShouldBeInTeamsRegion
2661 } Recommend = NoRecommend;
2662 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2663 // OpenMP [2.16, Nesting of Regions]
2664 // OpenMP constructs may not be nested inside a simd region.
2665 // OpenMP [2.8.1,simd Construct, Restrictions]
2666 // An ordered construct with the simd clause is the only OpenMP
2667 // construct that can appear in the simd region.
2668 // Allowing a SIMD construct nested in another SIMD construct is an
2669 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2670 // message.
2671 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2672 ? diag::err_omp_prohibited_region_simd
2673 : diag::warn_omp_nesting_simd);
2674 return CurrentRegion != OMPD_simd;
2675 }
2676 if (ParentRegion == OMPD_atomic) {
2677 // OpenMP [2.16, Nesting of Regions]
2678 // OpenMP constructs may not be nested inside an atomic region.
2679 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2680 return true;
2681 }
2682 if (CurrentRegion == OMPD_section) {
2683 // OpenMP [2.7.2, sections Construct, Restrictions]
2684 // Orphaned section directives are prohibited. That is, the section
2685 // directives must appear within the sections construct and must not be
2686 // encountered elsewhere in the sections region.
2687 if (ParentRegion != OMPD_sections &&
2688 ParentRegion != OMPD_parallel_sections) {
2689 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2690 << (ParentRegion != OMPD_unknown)
2691 << getOpenMPDirectiveName(ParentRegion);
2692 return true;
2693 }
2694 return false;
2695 }
2696 // Allow some constructs (except teams) to be orphaned (they could be
2697 // used in functions, called from OpenMP regions with the required
2698 // preconditions).
2699 if (ParentRegion == OMPD_unknown &&
2700 !isOpenMPNestingTeamsDirective(CurrentRegion))
2701 return false;
2702 if (CurrentRegion == OMPD_cancellation_point ||
2703 CurrentRegion == OMPD_cancel) {
2704 // OpenMP [2.16, Nesting of Regions]
2705 // A cancellation point construct for which construct-type-clause is
2706 // taskgroup must be nested inside a task construct. A cancellation
2707 // point construct for which construct-type-clause is not taskgroup must
2708 // be closely nested inside an OpenMP construct that matches the type
2709 // specified in construct-type-clause.
2710 // A cancel construct for which construct-type-clause is taskgroup must be
2711 // nested inside a task construct. A cancel construct for which
2712 // construct-type-clause is not taskgroup must be closely nested inside an
2713 // OpenMP construct that matches the type specified in
2714 // construct-type-clause.
2715 NestingProhibited =
2716 !((CancelRegion == OMPD_parallel &&
2717 (ParentRegion == OMPD_parallel ||
2718 ParentRegion == OMPD_target_parallel)) ||
2719 (CancelRegion == OMPD_for &&
2720 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2721 ParentRegion == OMPD_target_parallel_for ||
2722 ParentRegion == OMPD_distribute_parallel_for ||
2723 ParentRegion == OMPD_teams_distribute_parallel_for ||
2724 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2725 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2726 (CancelRegion == OMPD_sections &&
2727 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2728 ParentRegion == OMPD_parallel_sections)));
2729 } else if (CurrentRegion == OMPD_master) {
2730 // OpenMP [2.16, Nesting of Regions]
2731 // A master region may not be closely nested inside a worksharing,
2732 // atomic, or explicit task region.
2733 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2734 isOpenMPTaskingDirective(ParentRegion);
2735 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2736 // OpenMP [2.16, Nesting of Regions]
2737 // A critical region may not be nested (closely or otherwise) inside a
2738 // critical region with the same name. Note that this restriction is not
2739 // sufficient to prevent deadlock.
2740 SourceLocation PreviousCriticalLoc;
2741 bool DeadLock = Stack->hasDirective(
2742 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2743 const DeclarationNameInfo &DNI,
2744 SourceLocation Loc) -> bool {
2745 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2746 PreviousCriticalLoc = Loc;
2747 return true;
2748 } else
2749 return false;
2750 },
2751 false /* skip top directive */);
2752 if (DeadLock) {
2753 SemaRef.Diag(StartLoc,
2754 diag::err_omp_prohibited_region_critical_same_name)
2755 << CurrentName.getName();
2756 if (PreviousCriticalLoc.isValid())
2757 SemaRef.Diag(PreviousCriticalLoc,
2758 diag::note_omp_previous_critical_region);
2759 return true;
2760 }
2761 } else if (CurrentRegion == OMPD_barrier) {
2762 // OpenMP [2.16, Nesting of Regions]
2763 // A barrier region may not be closely nested inside a worksharing,
2764 // explicit task, critical, ordered, atomic, or master region.
2765 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2766 isOpenMPTaskingDirective(ParentRegion) ||
2767 ParentRegion == OMPD_master ||
2768 ParentRegion == OMPD_critical ||
2769 ParentRegion == OMPD_ordered;
2770 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2771 !isOpenMPParallelDirective(CurrentRegion) &&
2772 !isOpenMPTeamsDirective(CurrentRegion)) {
2773 // OpenMP [2.16, Nesting of Regions]
2774 // A worksharing region may not be closely nested inside a worksharing,
2775 // explicit task, critical, ordered, atomic, or master region.
2776 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2777 isOpenMPTaskingDirective(ParentRegion) ||
2778 ParentRegion == OMPD_master ||
2779 ParentRegion == OMPD_critical ||
2780 ParentRegion == OMPD_ordered;
2781 Recommend = ShouldBeInParallelRegion;
2782 } else if (CurrentRegion == OMPD_ordered) {
2783 // OpenMP [2.16, Nesting of Regions]
2784 // An ordered region may not be closely nested inside a critical,
2785 // atomic, or explicit task region.
2786 // An ordered region must be closely nested inside a loop region (or
2787 // parallel loop region) with an ordered clause.
2788 // OpenMP [2.8.1,simd Construct, Restrictions]
2789 // An ordered construct with the simd clause is the only OpenMP construct
2790 // that can appear in the simd region.
2791 NestingProhibited = ParentRegion == OMPD_critical ||
2792 isOpenMPTaskingDirective(ParentRegion) ||
2793 !(isOpenMPSimdDirective(ParentRegion) ||
2794 Stack->isParentOrderedRegion());
2795 Recommend = ShouldBeInOrderedRegion;
2796 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2797 // OpenMP [2.16, Nesting of Regions]
2798 // If specified, a teams construct must be contained within a target
2799 // construct.
2800 NestingProhibited = ParentRegion != OMPD_target;
2801 OrphanSeen = ParentRegion == OMPD_unknown;
2802 Recommend = ShouldBeInTargetRegion;
2803 }
2804 if (!NestingProhibited &&
2805 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2806 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2807 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2808 // OpenMP [2.16, Nesting of Regions]
2809 // distribute, parallel, parallel sections, parallel workshare, and the
2810 // parallel loop and parallel loop SIMD constructs are the only OpenMP
2811 // constructs that can be closely nested in the teams region.
2812 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2813 !isOpenMPDistributeDirective(CurrentRegion);
2814 Recommend = ShouldBeInParallelRegion;
2815 }
2816 if (!NestingProhibited &&
2817 isOpenMPNestingDistributeDirective(CurrentRegion)) {
2818 // OpenMP 4.5 [2.17 Nesting of Regions]
2819 // The region associated with the distribute construct must be strictly
2820 // nested inside a teams region
2821 NestingProhibited =
2822 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2823 Recommend = ShouldBeInTeamsRegion;
2824 }
2825 if (!NestingProhibited &&
2826 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2827 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2828 // OpenMP 4.5 [2.17 Nesting of Regions]
2829 // If a target, target update, target data, target enter data, or
2830 // target exit data construct is encountered during execution of a
2831 // target region, the behavior is unspecified.
2832 NestingProhibited = Stack->hasDirective(
2833 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2834 SourceLocation) -> bool {
2835 if (isOpenMPTargetExecutionDirective(K)) {
2836 OffendingRegion = K;
2837 return true;
2838 } else
2839 return false;
2840 },
2841 false /* don't skip top directive */);
2842 CloseNesting = false;
2843 }
2844 if (NestingProhibited) {
2845 if (OrphanSeen) {
2846 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2847 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2848 } else {
2849 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2850 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2851 << Recommend << getOpenMPDirectiveName(CurrentRegion);
2852 }
2853 return true;
2854 }
2855 }
2856 return false;
2857}
2858
2859static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2860 ArrayRef<OMPClause *> Clauses,
2861 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2862 bool ErrorFound = false;
2863 unsigned NamedModifiersNumber = 0;
2864 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2865 OMPD_unknown + 1);
2866 SmallVector<SourceLocation, 4> NameModifierLoc;
2867 for (const auto *C : Clauses) {
2868 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2869 // At most one if clause without a directive-name-modifier can appear on
2870 // the directive.
2871 OpenMPDirectiveKind CurNM = IC->getNameModifier();
2872 if (FoundNameModifiers[CurNM]) {
2873 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2874 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2875 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2876 ErrorFound = true;
2877 } else if (CurNM != OMPD_unknown) {
2878 NameModifierLoc.push_back(IC->getNameModifierLoc());
2879 ++NamedModifiersNumber;
2880 }
2881 FoundNameModifiers[CurNM] = IC;
2882 if (CurNM == OMPD_unknown)
2883 continue;
2884 // Check if the specified name modifier is allowed for the current
2885 // directive.
2886 // At most one if clause with the particular directive-name-modifier can
2887 // appear on the directive.
2888 bool MatchFound = false;
2889 for (auto NM : AllowedNameModifiers) {
2890 if (CurNM == NM) {
2891 MatchFound = true;
2892 break;
2893 }
2894 }
2895 if (!MatchFound) {
2896 S.Diag(IC->getNameModifierLoc(),
2897 diag::err_omp_wrong_if_directive_name_modifier)
2898 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
2899 ErrorFound = true;
2900 }
2901 }
2902 }
2903 // If any if clause on the directive includes a directive-name-modifier then
2904 // all if clauses on the directive must include a directive-name-modifier.
2905 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2906 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2907 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2908 diag::err_omp_no_more_if_clause);
2909 } else {
2910 std::string Values;
2911 std::string Sep(", ");
2912 unsigned AllowedCnt = 0;
2913 unsigned TotalAllowedNum =
2914 AllowedNameModifiers.size() - NamedModifiersNumber;
2915 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2916 ++Cnt) {
2917 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2918 if (!FoundNameModifiers[NM]) {
2919 Values += "'";
2920 Values += getOpenMPDirectiveName(NM);
2921 Values += "'";
2922 if (AllowedCnt + 2 == TotalAllowedNum)
2923 Values += " or ";
2924 else if (AllowedCnt + 1 != TotalAllowedNum)
2925 Values += Sep;
2926 ++AllowedCnt;
2927 }
2928 }
2929 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2930 diag::err_omp_unnamed_if_clause)
2931 << (TotalAllowedNum > 1) << Values;
2932 }
2933 for (auto Loc : NameModifierLoc) {
2934 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2935 }
2936 ErrorFound = true;
2937 }
2938 return ErrorFound;
2939}
2940
2941StmtResult Sema::ActOnOpenMPExecutableDirective(
2942 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2943 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2944 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2945 StmtResult Res = StmtError();
2946 // First check CancelRegion which is then used in checkNestingOfRegions.
2947 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2948 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
2949 StartLoc))
2950 return StmtError();
2951
2952 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2953 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2954 bool ErrorFound = false;
2955 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2956 if (AStmt && !CurContext->isDependentContext()) {
2957 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2957, __extension__ __PRETTY_FUNCTION__))
;
2958
2959 // Check default data sharing attributes for referenced variables.
2960 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
2961 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2962 Stmt *S = AStmt;
2963 while (--ThisCaptureLevel >= 0)
2964 S = cast<CapturedStmt>(S)->getCapturedStmt();
2965 DSAChecker.Visit(S);
2966 if (DSAChecker.isErrorFound())
2967 return StmtError();
2968 // Generate list of implicitly defined firstprivate variables.
2969 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2970
2971 SmallVector<Expr *, 4> ImplicitFirstprivates(
2972 DSAChecker.getImplicitFirstprivate().begin(),
2973 DSAChecker.getImplicitFirstprivate().end());
2974 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2975 DSAChecker.getImplicitMap().end());
2976 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2977 for (auto *C : Clauses) {
2978 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2979 for (auto *E : IRC->taskgroup_descriptors())
2980 if (E)
2981 ImplicitFirstprivates.emplace_back(E);
2982 }
2983 }
2984 if (!ImplicitFirstprivates.empty()) {
2985 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2986 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2987 SourceLocation())) {
2988 ClausesWithImplicit.push_back(Implicit);
2989 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2990 ImplicitFirstprivates.size();
2991 } else
2992 ErrorFound = true;
2993 }
2994 if (!ImplicitMaps.empty()) {
2995 if (OMPClause *Implicit = ActOnOpenMPMapClause(
2996 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2997 SourceLocation(), SourceLocation(), ImplicitMaps,
2998 SourceLocation(), SourceLocation(), SourceLocation())) {
2999 ClausesWithImplicit.emplace_back(Implicit);
3000 ErrorFound |=
3001 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3002 } else
3003 ErrorFound = true;
3004 }
3005 }
3006
3007 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3008 switch (Kind) {
3009 case OMPD_parallel:
3010 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3011 EndLoc);
3012 AllowedNameModifiers.push_back(OMPD_parallel);
3013 break;
3014 case OMPD_simd:
3015 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3016 VarsWithInheritedDSA);
3017 break;
3018 case OMPD_for:
3019 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3020 VarsWithInheritedDSA);
3021 break;
3022 case OMPD_for_simd:
3023 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3024 EndLoc, VarsWithInheritedDSA);
3025 break;
3026 case OMPD_sections:
3027 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3028 EndLoc);
3029 break;
3030 case OMPD_section:
3031 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp section' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3032, __extension__ __PRETTY_FUNCTION__))
3032 "No clauses are allowed for 'omp section' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp section' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3032, __extension__ __PRETTY_FUNCTION__))
;
3033 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3034 break;
3035 case OMPD_single:
3036 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3037 EndLoc);
3038 break;
3039 case OMPD_master:
3040 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp master' directive") ? void (
0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3041, __extension__ __PRETTY_FUNCTION__))
3041 "No clauses are allowed for 'omp master' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp master' directive") ? void (
0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3041, __extension__ __PRETTY_FUNCTION__))
;
3042 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3043 break;
3044 case OMPD_critical:
3045 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3046 StartLoc, EndLoc);
3047 break;
3048 case OMPD_parallel_for:
3049 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3050 EndLoc, VarsWithInheritedDSA);
3051 AllowedNameModifiers.push_back(OMPD_parallel);
3052 break;
3053 case OMPD_parallel_for_simd:
3054 Res = ActOnOpenMPParallelForSimdDirective(
3055 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3056 AllowedNameModifiers.push_back(OMPD_parallel);
3057 break;
3058 case OMPD_parallel_sections:
3059 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3060 StartLoc, EndLoc);
3061 AllowedNameModifiers.push_back(OMPD_parallel);
3062 break;
3063 case OMPD_task:
3064 Res =
3065 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3066 AllowedNameModifiers.push_back(OMPD_task);
3067 break;
3068 case OMPD_taskyield:
3069 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskyield' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3070, __extension__ __PRETTY_FUNCTION__))
3070 "No clauses are allowed for 'omp taskyield' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskyield' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3070, __extension__ __PRETTY_FUNCTION__))
;
3071 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3072, __extension__ __PRETTY_FUNCTION__))
3072 "No associated statement allowed for 'omp taskyield' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3072, __extension__ __PRETTY_FUNCTION__))
;
3073 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3074 break;
3075 case OMPD_barrier:
3076 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp barrier' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3077, __extension__ __PRETTY_FUNCTION__))
3077 "No clauses are allowed for 'omp barrier' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp barrier' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3077, __extension__ __PRETTY_FUNCTION__))
;
3078 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3079, __extension__ __PRETTY_FUNCTION__))
3079 "No associated statement allowed for 'omp barrier' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3079, __extension__ __PRETTY_FUNCTION__))
;
3080 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3081 break;
3082 case OMPD_taskwait:
3083 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskwait' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3084, __extension__ __PRETTY_FUNCTION__))
3084 "No clauses are allowed for 'omp taskwait' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp taskwait' directive") ? void
(0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3084, __extension__ __PRETTY_FUNCTION__))
;
3085 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3086, __extension__ __PRETTY_FUNCTION__))
3086 "No associated statement allowed for 'omp taskwait' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3086, __extension__ __PRETTY_FUNCTION__))
;
3087 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3088 break;
3089 case OMPD_taskgroup:
3090 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3091 EndLoc);
3092 break;
3093 case OMPD_flush:
3094 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3095, __extension__ __PRETTY_FUNCTION__))
3095 "No associated statement allowed for 'omp flush' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3095, __extension__ __PRETTY_FUNCTION__))
;
3096 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3097 break;
3098 case OMPD_ordered:
3099 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3100 EndLoc);
3101 break;
3102 case OMPD_atomic:
3103 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3104 EndLoc);
3105 break;
3106 case OMPD_teams:
3107 Res =
3108 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3109 break;
3110 case OMPD_target:
3111 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3112 EndLoc);
3113 AllowedNameModifiers.push_back(OMPD_target);
3114 break;
3115 case OMPD_target_parallel:
3116 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3117 StartLoc, EndLoc);
3118 AllowedNameModifiers.push_back(OMPD_target);
3119 AllowedNameModifiers.push_back(OMPD_parallel);
3120 break;
3121 case OMPD_target_parallel_for:
3122 Res = ActOnOpenMPTargetParallelForDirective(
3123 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3124 AllowedNameModifiers.push_back(OMPD_target);
3125 AllowedNameModifiers.push_back(OMPD_parallel);
3126 break;
3127 case OMPD_cancellation_point:
3128 assert(ClausesWithImplicit.empty() &&(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp cancellation point' directive"
) ? void (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3129, __extension__ __PRETTY_FUNCTION__))
3129 "No clauses are allowed for 'omp cancellation point' directive")(static_cast <bool> (ClausesWithImplicit.empty() &&
"No clauses are allowed for 'omp cancellation point' directive"
) ? void (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3129, __extension__ __PRETTY_FUNCTION__))
;
3130 assert(AStmt == nullptr && "No associated statement allowed for 'omp "(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? void (0) : __assert_fail (
"AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3131, __extension__ __PRETTY_FUNCTION__))
3131 "cancellation point' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? void (0) : __assert_fail (
"AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3131, __extension__ __PRETTY_FUNCTION__))
;
3132 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3133 break;
3134 case OMPD_cancel:
3135 assert(AStmt == nullptr &&(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3136, __extension__ __PRETTY_FUNCTION__))
3136 "No associated statement allowed for 'omp cancel' directive")(static_cast <bool> (AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? void (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3136, __extension__ __PRETTY_FUNCTION__))
;
3137 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3138 CancelRegion);
3139 AllowedNameModifiers.push_back(OMPD_cancel);
3140 break;
3141 case OMPD_target_data:
3142 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3143 EndLoc);
3144 AllowedNameModifiers.push_back(OMPD_target_data);
3145 break;
3146 case OMPD_target_enter_data:
3147 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3148 EndLoc, AStmt);
3149 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3150 break;
3151 case OMPD_target_exit_data:
3152 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3153 EndLoc, AStmt);
3154 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3155 break;
3156 case OMPD_taskloop:
3157 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3158 EndLoc, VarsWithInheritedDSA);
3159 AllowedNameModifiers.push_back(OMPD_taskloop);
3160 break;
3161 case OMPD_taskloop_simd:
3162 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3163 EndLoc, VarsWithInheritedDSA);
3164 AllowedNameModifiers.push_back(OMPD_taskloop);
3165 break;
3166 case OMPD_distribute:
3167 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3168 EndLoc, VarsWithInheritedDSA);
3169 break;
3170 case OMPD_target_update:
3171 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3172 EndLoc, AStmt);
3173 AllowedNameModifiers.push_back(OMPD_target_update);
3174 break;
3175 case OMPD_distribute_parallel_for:
3176 Res = ActOnOpenMPDistributeParallelForDirective(
3177 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3178 AllowedNameModifiers.push_back(OMPD_parallel);
3179 break;
3180 case OMPD_distribute_parallel_for_simd:
3181 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3182 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3183 AllowedNameModifiers.push_back(OMPD_parallel);
3184 break;
3185 case OMPD_distribute_simd:
3186 Res = ActOnOpenMPDistributeSimdDirective(
3187 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3188 break;
3189 case OMPD_target_parallel_for_simd:
3190 Res = ActOnOpenMPTargetParallelForSimdDirective(
3191 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3192 AllowedNameModifiers.push_back(OMPD_target);
3193 AllowedNameModifiers.push_back(OMPD_parallel);
3194 break;
3195 case OMPD_target_simd:
3196 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3197 EndLoc, VarsWithInheritedDSA);
3198 AllowedNameModifiers.push_back(OMPD_target);
3199 break;
3200 case OMPD_teams_distribute:
3201 Res = ActOnOpenMPTeamsDistributeDirective(
3202 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3203 break;
3204 case OMPD_teams_distribute_simd:
3205 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3206 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3207 break;
3208 case OMPD_teams_distribute_parallel_for_simd:
3209 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3210 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3211 AllowedNameModifiers.push_back(OMPD_parallel);
3212 break;
3213 case OMPD_teams_distribute_parallel_for:
3214 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3215 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3216 AllowedNameModifiers.push_back(OMPD_parallel);
3217 break;
3218 case OMPD_target_teams:
3219 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3220 EndLoc);
3221 AllowedNameModifiers.push_back(OMPD_target);
3222 break;
3223 case OMPD_target_teams_distribute:
3224 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3225 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3226 AllowedNameModifiers.push_back(OMPD_target);
3227 break;
3228 case OMPD_target_teams_distribute_parallel_for:
3229 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3230 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3231 AllowedNameModifiers.push_back(OMPD_target);
3232 AllowedNameModifiers.push_back(OMPD_parallel);
3233 break;
3234 case OMPD_target_teams_distribute_parallel_for_simd:
3235 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3236 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3237 AllowedNameModifiers.push_back(OMPD_target);
3238 AllowedNameModifiers.push_back(OMPD_parallel);
3239 break;
3240 case OMPD_target_teams_distribute_simd:
3241 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3242 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3243 AllowedNameModifiers.push_back(OMPD_target);
3244 break;
3245 case OMPD_declare_target:
3246 case OMPD_end_declare_target:
3247 case OMPD_threadprivate:
3248 case OMPD_declare_reduction:
3249 case OMPD_declare_simd:
3250 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3250)
;
3251 case OMPD_unknown:
3252 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3252)
;
3253 }
3254
3255 for (auto P : VarsWithInheritedDSA) {
3256 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3257 << P.first << P.second->getSourceRange();
3258 }
3259 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3260
3261 if (!AllowedNameModifiers.empty())
3262 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3263 ErrorFound;
3264
3265 if (ErrorFound)
3266 return StmtError();
3267 return Res;
3268}
3269
3270Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3271 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3272 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3273 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3274 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3275 assert(Aligneds.size() == Alignments.size())(static_cast <bool> (Aligneds.size() == Alignments.size
()) ? void (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3275, __extension__ __PRETTY_FUNCTION__))
;
3276 assert(Linears.size() == LinModifiers.size())(static_cast <bool> (Linears.size() == LinModifiers.size
()) ? void (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3276, __extension__ __PRETTY_FUNCTION__))
;
3277 assert(Linears.size() == Steps.size())(static_cast <bool> (Linears.size() == Steps.size()) ? void
(0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3277, __extension__ __PRETTY_FUNCTION__))
;
3278 if (!DG || DG.get().isNull())
3279 return DeclGroupPtrTy();
3280
3281 if (!DG.get().isSingleDecl()) {
3282 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3283 return DG;
3284 }
3285 auto *ADecl = DG.get().getSingleDecl();
3286 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3287 ADecl = FTD->getTemplatedDecl();
3288
3289 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3290 if (!FD) {
3291 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3292 return DeclGroupPtrTy();
3293 }
3294
3295 // OpenMP [2.8.2, declare simd construct, Description]
3296 // The parameter of the simdlen clause must be a constant positive integer
3297 // expression.
3298 ExprResult SL;
3299 if (Simdlen)
3300 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3301 // OpenMP [2.8.2, declare simd construct, Description]
3302 // The special this pointer can be used as if was one of the arguments to the
3303 // function in any of the linear, aligned, or uniform clauses.
3304 // The uniform clause declares one or more arguments to have an invariant
3305 // value for all concurrent invocations of the function in the execution of a
3306 // single SIMD loop.
3307 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3308 Expr *UniformedLinearThis = nullptr;
3309 for (auto *E : Uniforms) {
3310 E = E->IgnoreParenImpCasts();
3311 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3312 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3313 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3314 FD->getParamDecl(PVD->getFunctionScopeIndex())
3315 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3316 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3317 continue;
3318 }
3319 if (isa<CXXThisExpr>(E)) {
3320 UniformedLinearThis = E;
3321 continue;
3322 }
3323 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3324 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3325 }
3326 // OpenMP [2.8.2, declare simd construct, Description]
3327 // The aligned clause declares that the object to which each list item points
3328 // is aligned to the number of bytes expressed in the optional parameter of
3329 // the aligned clause.
3330 // The special this pointer can be used as if was one of the arguments to the
3331 // function in any of the linear, aligned, or uniform clauses.
3332 // The type of list items appearing in the aligned clause must be array,
3333 // pointer, reference to array, or reference to pointer.
3334 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3335 Expr *AlignedThis = nullptr;
3336 for (auto *E : Aligneds) {
3337 E = E->IgnoreParenImpCasts();
3338 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3339 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3340 auto *CanonPVD = PVD->getCanonicalDecl();
3341 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3342 FD->getParamDecl(PVD->getFunctionScopeIndex())
3343 ->getCanonicalDecl() == CanonPVD) {
3344 // OpenMP [2.8.1, simd construct, Restrictions]
3345 // A list-item cannot appear in more than one aligned clause.
3346 if (AlignedArgs.count(CanonPVD) > 0) {
3347 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3348 << 1 << E->getSourceRange();
3349 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3350 diag::note_omp_explicit_dsa)
3351 << getOpenMPClauseName(OMPC_aligned);
3352 continue;
3353 }
3354 AlignedArgs[CanonPVD] = E;
3355 QualType QTy = PVD->getType()
3356 .getNonReferenceType()
3357 .getUnqualifiedType()
3358 .getCanonicalType();
3359 const Type *Ty = QTy.getTypePtrOrNull();
3360 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3361 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3362 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3363 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3364 }
3365 continue;
3366 }
3367 }
3368 if (isa<CXXThisExpr>(E)) {
3369 if (AlignedThis) {
3370 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3371 << 2 << E->getSourceRange();
3372 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3373 << getOpenMPClauseName(OMPC_aligned);
3374 }
3375 AlignedThis = E;
3376 continue;
3377 }
3378 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3379 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3380 }
3381 // The optional parameter of the aligned clause, alignment, must be a constant
3382 // positive integer expression. If no optional parameter is specified,
3383 // implementation-defined default alignments for SIMD instructions on the
3384 // target platforms are assumed.
3385 SmallVector<Expr *, 4> NewAligns;
3386 for (auto *E : Alignments) {
3387 ExprResult Align;
3388 if (E)
3389 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3390 NewAligns.push_back(Align.get());
3391 }
3392 // OpenMP [2.8.2, declare simd construct, Description]
3393 // The linear clause declares one or more list items to be private to a SIMD
3394 // lane and to have a linear relationship with respect to the iteration space
3395 // of a loop.
3396 // The special this pointer can be used as if was one of the arguments to the
3397 // function in any of the linear, aligned, or uniform clauses.
3398 // When a linear-step expression is specified in a linear clause it must be
3399 // either a constant integer expression or an integer-typed parameter that is
3400 // specified in a uniform clause on the directive.
3401 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3402 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3403 auto MI = LinModifiers.begin();
3404 for (auto *E : Linears) {
3405 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3406 ++MI;
3407 E = E->IgnoreParenImpCasts();
3408 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3409 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3410 auto *CanonPVD = PVD->getCanonicalDecl();
3411 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3412 FD->getParamDecl(PVD->getFunctionScopeIndex())
3413 ->getCanonicalDecl() == CanonPVD) {
3414 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3415 // A list-item cannot appear in more than one linear clause.
3416 if (LinearArgs.count(CanonPVD) > 0) {
3417 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3418 << getOpenMPClauseName(OMPC_linear)
3419 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3420 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3421 diag::note_omp_explicit_dsa)
3422 << getOpenMPClauseName(OMPC_linear);
3423 continue;
3424 }
3425 // Each argument can appear in at most one uniform or linear clause.
3426 if (UniformedArgs.count(CanonPVD) > 0) {
3427 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3428 << getOpenMPClauseName(OMPC_linear)
3429 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3430 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3431 diag::note_omp_explicit_dsa)
3432 << getOpenMPClauseName(OMPC_uniform);
3433 continue;
3434 }
3435 LinearArgs[CanonPVD] = E;
3436 if (E->isValueDependent() || E->isTypeDependent() ||
3437 E->isInstantiationDependent() ||
3438 E->containsUnexpandedParameterPack())
3439 continue;
3440 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3441 PVD->getOriginalType());
3442 continue;
3443 }
3444 }
3445 if (isa<CXXThisExpr>(E)) {
3446 if (UniformedLinearThis) {
3447 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3448 << getOpenMPClauseName(OMPC_linear)
3449 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3450 << E->getSourceRange();
3451 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3452 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3453 : OMPC_linear);
3454 continue;
3455 }
3456 UniformedLinearThis = E;
3457 if (E->isValueDependent() || E->isTypeDependent() ||
3458 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3459 continue;
3460 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3461 E->getType());
3462 continue;
3463 }
3464 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3465 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3466 }
3467 Expr *Step = nullptr;
3468 Expr *NewStep = nullptr;
3469 SmallVector<Expr *, 4> NewSteps;
3470 for (auto *E : Steps) {
3471 // Skip the same step expression, it was checked already.
3472 if (Step == E || !E) {
3473 NewSteps.push_back(E ? NewStep : nullptr);
3474 continue;
3475 }
3476 Step = E;
3477 if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3478 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3479 auto *CanonPVD = PVD->getCanonicalDecl();
3480 if (UniformedArgs.count(CanonPVD) == 0) {
3481 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3482 << Step->getSourceRange();
3483 } else if (E->isValueDependent() || E->isTypeDependent() ||
3484 E->isInstantiationDependent() ||
3485 E->containsUnexpandedParameterPack() ||
3486 CanonPVD->getType()->hasIntegerRepresentation())
3487 NewSteps.push_back(Step);
3488 else {
3489 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3490 << Step->getSourceRange();
3491 }
3492 continue;
3493 }
3494 NewStep = Step;
3495 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3496 !Step->isInstantiationDependent() &&
3497 !Step->containsUnexpandedParameterPack()) {
3498 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3499 .get();
3500 if (NewStep)
3501 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3502 }
3503 NewSteps.push_back(NewStep);
3504 }
3505 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3506 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3507 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3508 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3509 const_cast<Expr **>(Linears.data()), Linears.size(),
3510 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3511 NewSteps.data(), NewSteps.size(), SR);
3512 ADecl->addAttr(NewAttr);
3513 return ConvertDeclToDeclGroup(ADecl);
3514}
3515
3516StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3517 Stmt *AStmt,
3518 SourceLocation StartLoc,
3519 SourceLocation EndLoc) {
3520 if (!AStmt)
3521 return StmtError();
3522
3523 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3524 // 1.2.2 OpenMP Language Terminology
3525 // Structured block - An executable statement with a single entry at the
3526 // top and a single exit at the bottom.
3527 // The point of exit cannot be a branch out of the structured block.
3528 // longjmp() and throw() must not violate the entry/exit criteria.
3529 CS->getCapturedDecl()->setNothrow();
3530
3531 getCurFunction()->setHasBranchProtectedScope();
3532
3533 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3534 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
3535}
3536
3537namespace {
3538/// \brief Helper class for checking canonical form of the OpenMP loops and
3539/// extracting iteration space of each loop in the loop nest, that will be used
3540/// for IR generation.
3541class OpenMPIterationSpaceChecker {
3542 /// \brief Reference to Sema.
3543 Sema &SemaRef;
3544 /// \brief A location for diagnostics (when there is no some better location).
3545 SourceLocation DefaultLoc;
3546 /// \brief A location for diagnostics (when increment is not compatible).
3547 SourceLocation ConditionLoc;
3548 /// \brief A source location for referring to loop init later.
3549 SourceRange InitSrcRange;
3550 /// \brief A source location for referring to condition later.
3551 SourceRange ConditionSrcRange;
3552 /// \brief A source location for referring to increment later.
3553 SourceRange IncrementSrcRange;
3554 /// \brief Loop variable.
3555 ValueDecl *LCDecl = nullptr;
3556 /// \brief Reference to loop variable.
3557 Expr *LCRef = nullptr;
3558 /// \brief Lower bound (initializer for the var).
3559 Expr *LB = nullptr;
3560 /// \brief Upper bound.
3561 Expr *UB = nullptr;
3562 /// \brief Loop step (increment).
3563 Expr *Step = nullptr;
3564 /// \brief This flag is true when condition is one of:
3565 /// Var < UB
3566 /// Var <= UB
3567 /// UB > Var
3568 /// UB >= Var
3569 bool TestIsLessOp = false;
3570 /// \brief This flag is true when condition is strict ( < or > ).
3571 bool TestIsStrictOp = false;
3572 /// \brief This flag is true when step is subtracted on each iteration.
3573 bool SubtractStep = false;
3574
3575public:
3576 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3577 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3578 /// \brief Check init-expr for canonical loop form and save loop counter
3579 /// variable - #Var and its initialization value - #LB.
3580 bool CheckInit(Stmt *S, bool EmitDiags = true);
3581 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3582 /// for less/greater and for strict/non-strict comparison.
3583 bool CheckCond(Expr *S);
3584 /// \brief Check incr-expr for canonical loop form and return true if it
3585 /// does not conform, otherwise save loop step (#Step).
3586 bool CheckInc(Expr *S);
3587 /// \brief Return the loop counter variable.
3588 ValueDecl *GetLoopDecl() const { return LCDecl; }
3589 /// \brief Return the reference expression to loop counter variable.
3590 Expr *GetLoopDeclRefExpr() const { return LCRef; }
3591 /// \brief Source range of the loop init.
3592 SourceRange GetInitSrcRange() const { return InitSrcRange; }
3593 /// \brief Source range of the loop condition.
3594 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3595 /// \brief Source range of the loop increment.
3596 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3597 /// \brief True if the step should be subtracted.
3598 bool ShouldSubtractStep() const { return SubtractStep; }
3599 /// \brief Build the expression to calculate the number of iterations.
3600 Expr *
3601 BuildNumIterations(Scope *S, const bool LimitedType,
3602 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3603 /// \brief Build the precondition expression for the loops.
3604 Expr *BuildPreCond(Scope *S, Expr *Cond,
3605 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3606 /// \brief Build reference expression to the counter be used for codegen.
3607 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3608 DSAStackTy &DSA) const;
3609 /// \brief Build reference expression to the private counter be used for
3610 /// codegen.
3611 Expr *BuildPrivateCounterVar() const;
3612 /// \brief Build initialization of the counter be used for codegen.
3613 Expr *BuildCounterInit() const;
3614 /// \brief Build step of the counter be used for codegen.
3615 Expr *BuildCounterStep() const;
3616 /// \brief Return true if any expression is dependent.
3617 bool Dependent() const;
3618
3619private:
3620 /// \brief Check the right-hand side of an assignment in the increment
3621 /// expression.
3622 bool CheckIncRHS(Expr *RHS);
3623 /// \brief Helper to set loop counter variable and its initializer.
3624 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3625 /// \brief Helper to set upper bound.
3626 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3627 SourceLocation SL);
3628 /// \brief Helper to set loop increment.
3629 bool SetStep(Expr *NewStep, bool Subtract);
3630};
3631
3632bool OpenMPIterationSpaceChecker::Dependent() const {
3633 if (!LCDecl) {
3634 assert(!LB && !UB && !Step)(static_cast <bool> (!LB && !UB && !Step
) ? void (0) : __assert_fail ("!LB && !UB && !Step"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3634, __extension__ __PRETTY_FUNCTION__))
;
3635 return false;
3636 }
3637 return LCDecl->getType()->isDependentType() ||
3638 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3639 (Step && Step->isValueDependent());
3640}
3641
3642bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3643 Expr *NewLCRefExpr,
3644 Expr *NewLB) {
3645 // State consistency checking to ensure correct usage.
3646 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&(static_cast <bool> (LCDecl == nullptr && LB ==
nullptr && LCRef == nullptr && UB == nullptr
&& Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? void (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3647, __extension__ __PRETTY_FUNCTION__))
3647 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast <bool> (LCDecl == nullptr && LB ==
nullptr && LCRef == nullptr && UB == nullptr
&& Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? void (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3647, __extension__ __PRETTY_FUNCTION__))
;
3648 if (!NewLCDecl || !NewLB)
3649 return true;
3650 LCDecl = getCanonicalDecl(NewLCDecl);
3651 LCRef = NewLCRefExpr;
3652 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3653 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3654 if ((Ctor->isCopyOrMoveConstructor() ||
3655 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3656 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3657 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3658 LB = NewLB;
3659 return false;
3660}
3661
3662bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3663 SourceRange SR, SourceLocation SL) {
3664 // State consistency checking to ensure correct usage.
3665 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && UB == nullptr && Step == nullptr &&
!TestIsLessOp && !TestIsStrictOp) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3666, __extension__ __PRETTY_FUNCTION__))
3666 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && UB == nullptr && Step == nullptr &&
!TestIsLessOp && !TestIsStrictOp) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3666, __extension__ __PRETTY_FUNCTION__))
;
3667 if (!NewUB)
3668 return true;
3669 UB = NewUB;
3670 TestIsLessOp = LessOp;
3671 TestIsStrictOp = StrictOp;
3672 ConditionSrcRange = SR;
3673 ConditionLoc = SL;
3674 return false;
3675}
3676
3677bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3678 // State consistency checking to ensure correct usage.
3679 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)(static_cast <bool> (LCDecl != nullptr && LB !=
nullptr && Step == nullptr) ? void (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3679, __extension__ __PRETTY_FUNCTION__))
;
3680 if (!NewStep)
3681 return true;
3682 if (!NewStep->isValueDependent()) {
3683 // Check that the step is integer expression.
3684 SourceLocation StepLoc = NewStep->getLocStart();
3685 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3686 StepLoc, getExprAsWritten(NewStep));
3687 if (Val.isInvalid())
3688 return true;
3689 NewStep = Val.get();
3690
3691 // OpenMP [2.6, Canonical Loop Form, Restrictions]
3692 // If test-expr is of form var relational-op b and relational-op is < or
3693 // <= then incr-expr must cause var to increase on each iteration of the
3694 // loop. If test-expr is of form var relational-op b and relational-op is
3695 // > or >= then incr-expr must cause var to decrease on each iteration of
3696 // the loop.
3697 // If test-expr is of form b relational-op var and relational-op is < or
3698 // <= then incr-expr must cause var to decrease on each iteration of the
3699 // loop. If test-expr is of form b relational-op var and relational-op is
3700 // > or >= then incr-expr must cause var to increase on each iteration of
3701 // the loop.
3702 llvm::APSInt Result;
3703 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3704 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3705 bool IsConstNeg =
3706 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3707 bool IsConstPos =
3708 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3709 bool IsConstZero = IsConstant && !Result.getBoolValue();
3710 if (UB && (IsConstZero ||
3711 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3712 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3713 SemaRef.Diag(NewStep->getExprLoc(),
3714 diag::err_omp_loop_incr_not_compatible)
3715 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3716 SemaRef.Diag(ConditionLoc,
3717 diag::note_omp_loop_cond_requres_compatible_incr)
3718 << TestIsLessOp << ConditionSrcRange;
3719 return true;
3720 }
3721 if (TestIsLessOp == Subtract) {
3722 NewStep =
3723 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3724 .get();
3725 Subtract = !Subtract;
3726 }
3727 }
3728
3729 Step = NewStep;
3730 SubtractStep = Subtract;
3731 return false;
3732}
3733
3734bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3735 // Check init-expr for canonical loop form and save loop counter
3736 // variable - #Var and its initialization value - #LB.
3737 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3738 // var = lb
3739 // integer-type var = lb
3740 // random-access-iterator-type var = lb
3741 // pointer-type var = lb
3742 //
3743 if (!S) {
3744 if (EmitDiags) {
3745 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3746 }
3747 return true;
3748 }
3749 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3750 if (!ExprTemp->cleanupsHaveSideEffects())
3751 S = ExprTemp->getSubExpr();
3752
3753 InitSrcRange = S->getSourceRange();
3754 if (Expr *E = dyn_cast<Expr>(S))
3755 S = E->IgnoreParens();
3756 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3757 if (BO->getOpcode() == BO_Assign) {
3758 auto *LHS = BO->getLHS()->IgnoreParens();
3759 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3760 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3761 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3762 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3763 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3764 }
3765 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3766 if (ME->isArrow() &&
3767 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3768 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3769 }
3770 }
3771 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3772 if (DS->isSingleDecl()) {
3773 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3774 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3775 // Accept non-canonical init form here but emit ext. warning.
3776 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3777 SemaRef.Diag(S->getLocStart(),
3778 diag::ext_omp_loop_not_canonical_init)
3779 << S->getSourceRange();
3780 return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3781 }
3782 }
3783 }
3784 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3785 if (CE->getOperator() == OO_Equal) {
3786 auto *LHS = CE->getArg(0);
3787 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3788 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3789 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3790 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3791 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3792 }
3793 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3794 if (ME->isArrow() &&
3795 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3796 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3797 }
3798 }
3799 }
3800
3801 if (Dependent() || SemaRef.CurContext->isDependentContext())
3802 return false;
3803 if (EmitDiags) {
3804 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3805 << S->getSourceRange();
3806 }
3807 return true;
3808}
3809
3810/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3811/// variable (which may be the loop variable) if possible.
3812static const ValueDecl *GetInitLCDecl(Expr *E) {
3813 if (!E)
3814 return nullptr;
3815 E = getExprAsWritten(E);
3816 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3817 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3818 if ((Ctor->isCopyOrMoveConstructor() ||
3819 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3820 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3821 E = CE->getArg(0)->IgnoreParenImpCasts();
3822 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3823 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3824 return getCanonicalDecl(VD);
3825 }
3826 if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3827 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3828 return getCanonicalDecl(ME->getMemberDecl());
3829 return nullptr;
3830}
3831
3832bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3833 // Check test-expr for canonical form, save upper-bound UB, flags for
3834 // less/greater and for strict/non-strict comparison.
3835 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3836 // var relational-op b
3837 // b relational-op var
3838 //
3839 if (!S) {
3840 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3841 return true;
3842 }
3843 S = getExprAsWritten(S);
3844 SourceLocation CondLoc = S->getLocStart();
3845 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3846 if (BO->isRelationalOp()) {
3847 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3848 return SetUB(BO->getRHS(),
3849 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3850 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3851 BO->getSourceRange(), BO->getOperatorLoc());
3852 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3853 return SetUB(BO->getLHS(),
3854 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3855 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3856 BO->getSourceRange(), BO->getOperatorLoc());
3857 }
3858 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3859 if (CE->getNumArgs() == 2) {
3860 auto Op = CE->getOperator();
3861 switch (Op) {
3862 case OO_Greater:
3863 case OO_GreaterEqual:
3864 case OO_Less:
3865 case OO_LessEqual:
3866 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3867 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3868 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3869 CE->getOperatorLoc());
3870 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3871 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3872 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3873 CE->getOperatorLoc());
3874 break;
3875 default:
3876 break;
3877 }
3878 }
3879 }
3880 if (Dependent() || SemaRef.CurContext->isDependentContext())
3881 return false;
3882 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3883 << S->getSourceRange() << LCDecl;
3884 return true;
3885}
3886
3887bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3888 // RHS of canonical loop form increment can be:
3889 // var + incr
3890 // incr + var
3891 // var - incr
3892 //
3893 RHS = RHS->IgnoreParenImpCasts();
3894 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3895 if (BO->isAdditiveOp()) {
3896 bool IsAdd = BO->getOpcode() == BO_Add;
3897 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3898 return SetStep(BO->getRHS(), !IsAdd);
3899 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3900 return SetStep(BO->getLHS(), false);
3901 }
3902 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3903 bool IsAdd = CE->getOperator() == OO_Plus;
3904 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3905 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3906 return SetStep(CE->getArg(1), !IsAdd);
3907 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3908 return SetStep(CE->getArg(0), false);
3909 }
3910 }
3911 if (Dependent() || SemaRef.CurContext->isDependentContext())
3912 return false;
3913 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3914 << RHS->getSourceRange() << LCDecl;
3915 return true;
3916}
3917
3918bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3919 // Check incr-expr for canonical loop form and return true if it
3920 // does not conform.
3921 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3922 // ++var
3923 // var++
3924 // --var
3925 // var--
3926 // var += incr
3927 // var -= incr
3928 // var = var + incr
3929 // var = incr + var
3930 // var = var - incr
3931 //
3932 if (!S) {
3933 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3934 return true;
3935 }
3936 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3937 if (!ExprTemp->cleanupsHaveSideEffects())
3938 S = ExprTemp->getSubExpr();
3939
3940 IncrementSrcRange = S->getSourceRange();
3941 S = S->IgnoreParens();
3942 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3943 if (UO->isIncrementDecrementOp() &&
3944 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3945 return SetStep(SemaRef
3946 .ActOnIntegerConstant(UO->getLocStart(),
3947 (UO->isDecrementOp() ? -1 : 1))
3948 .get(),
3949 false);
3950 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3951 switch (BO->getOpcode()) {
3952 case BO_AddAssign:
3953 case BO_SubAssign:
3954 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3955 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3956 break;
3957 case BO_Assign:
3958 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3959 return CheckIncRHS(BO->getRHS());
3960 break;
3961 default:
3962 break;
3963 }
3964 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3965 switch (CE->getOperator()) {
3966 case OO_PlusPlus:
3967 case OO_MinusMinus:
3968 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3969 return SetStep(SemaRef
3970 .ActOnIntegerConstant(
3971 CE->getLocStart(),
3972 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3973 .get(),
3974 false);
3975 break;
3976 case OO_PlusEqual:
3977 case OO_MinusEqual:
3978 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3979 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3980 break;
3981 case OO_Equal:
3982 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3983 return CheckIncRHS(CE->getArg(1));
3984 break;
3985 default:
3986 break;
3987 }
3988 }
3989 if (Dependent() || SemaRef.CurContext->isDependentContext())
3990 return false;
3991 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3992 << S->getSourceRange() << LCDecl;
3993 return true;
3994}
3995
3996static ExprResult
3997tryBuildCapture(Sema &SemaRef, Expr *Capture,
3998 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3999 if (SemaRef.CurContext->isDependentContext())
4000 return ExprResult(Capture);
4001 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4002 return SemaRef.PerformImplicitConversion(
4003 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4004 /*AllowExplicit=*/true);
4005 auto I = Captures.find(Capture);
4006 if (I != Captures.end())
4007 return buildCapture(SemaRef, Capture, I->second);
4008 DeclRefExpr *Ref = nullptr;
4009 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4010 Captures[Capture] = Ref;
4011 return Res;
4012}
4013
4014/// \brief Build the expression to calculate the number of iterations.
4015Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
4016 Scope *S, const bool LimitedType,
4017 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4018 ExprResult Diff;
4019 auto VarType = LCDecl->getType().getNonReferenceType();
4020 if (VarType->isIntegerType() || VarType->isPointerType() ||
4021 SemaRef.getLangOpts().CPlusPlus) {
4022 // Upper - Lower
4023 auto *UBExpr = TestIsLessOp ? UB : LB;
4024 auto *LBExpr = TestIsLessOp ? LB : UB;
4025 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4026 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4027 if (!Upper || !Lower)
4028 return nullptr;
4029
4030 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4031
4032 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4033 // BuildBinOp already emitted error, this one is to point user to upper
4034 // and lower bound, and to tell what is passed to 'operator-'.
4035 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4036 << Upper->getSourceRange() << Lower->getSourceRange();
4037 return nullptr;
4038 }
4039 }
4040
4041 if (!Diff.isUsable())
4042 return nullptr;
4043
4044 // Upper - Lower [- 1]
4045 if (TestIsStrictOp)
4046 Diff = SemaRef.BuildBinOp(
4047 S, DefaultLoc, BO_Sub, Diff.get(),
4048 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4049 if (!Diff.isUsable())
4050 return nullptr;
4051
4052 // Upper - Lower [- 1] + Step
4053 auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
4054 if (!NewStep.isUsable())
4055 return nullptr;
4056 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4057 if (!Diff.isUsable())
4058 return nullptr;
4059
4060 // Parentheses (for dumping/debugging purposes only).
4061 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4062 if (!Diff.isUsable())
4063 return nullptr;
4064
4065 // (Upper - Lower [- 1] + Step) / Step
4066 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4067 if (!Diff.isUsable())
4068 return nullptr;
4069
4070 // OpenMP runtime requires 32-bit or 64-bit loop variables.
4071 QualType Type = Diff.get()->getType();
4072 auto &C = SemaRef.Context;
4073 bool UseVarType = VarType->hasIntegerRepresentation() &&
4074 C.getTypeSize(Type) > C.getTypeSize(VarType);
4075 if (!Type->isIntegerType() || UseVarType) {
4076 unsigned NewSize =
4077 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4078 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4079 : Type->hasSignedIntegerRepresentation();
4080 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4081 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4082 Diff = SemaRef.PerformImplicitConversion(
4083 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4084 if (!Diff.isUsable())
4085 return nullptr;
4086 }
4087 }
4088 if (LimitedType) {
4089 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4090 if (NewSize != C.getTypeSize(Type)) {
4091 if (NewSize < C.getTypeSize(Type)) {
4092 assert(NewSize == 64 && "incorrect loop var size")(static_cast <bool> (NewSize == 64 && "incorrect loop var size"
) ? void (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4092, __extension__ __PRETTY_FUNCTION__))
;
4093 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4094 << InitSrcRange << ConditionSrcRange;
4095 }
4096 QualType NewType = C.getIntTypeForBitwidth(
4097 NewSize, Type->hasSignedIntegerRepresentation() ||
4098 C.getTypeSize(Type) < NewSize);
4099 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4100 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4101 Sema::AA_Converting, true);
4102 if (!Diff.isUsable())
4103 return nullptr;
4104 }
4105 }
4106 }
4107
4108 return Diff.get();
4109}
4110
4111Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4112 Scope *S, Expr *Cond,
4113 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4114 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4115 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4116 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4117
4118 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4119 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4120 if (!NewLB.isUsable() || !NewUB.isUsable())
4121 return nullptr;
4122
4123 auto CondExpr = SemaRef.BuildBinOp(
4124 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4125 : (TestIsStrictOp ? BO_GT : BO_GE),
4126 NewLB.get(), NewUB.get());
4127 if (CondExpr.isUsable()) {
4128 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4129 SemaRef.Context.BoolTy))
4130 CondExpr = SemaRef.PerformImplicitConversion(
4131 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4132 /*AllowExplicit=*/true);
4133 }
4134 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4135 // Otherwise use original loop conditon and evaluate it in runtime.
4136 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4137}
4138
4139/// \brief Build reference expression to the counter be used for codegen.
4140DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4141 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4142 auto *VD = dyn_cast<VarDecl>(LCDecl);
4143 if (!VD) {
4144 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4145 auto *Ref = buildDeclRefExpr(
4146 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4147 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4148 // If the loop control decl is explicitly marked as private, do not mark it
4149 // as captured again.
4150 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4151 Captures.insert(std::make_pair(LCRef, Ref));
4152 return Ref;
4153 }
4154 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4155 DefaultLoc);
4156}
4157
4158Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4159 if (LCDecl && !LCDecl->isInvalidDecl()) {
4160 auto Type = LCDecl->getType().getNonReferenceType();
4161 auto *PrivateVar =
4162 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4163 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4164 if (PrivateVar->isInvalidDecl())
4165 return nullptr;
4166 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4167 }
4168 return nullptr;
4169}
4170
4171/// \brief Build initialization of the counter to be used for codegen.
4172Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
4173
4174/// \brief Build step of the counter be used for codegen.
4175Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4176
4177/// \brief Iteration space of a single for loop.
4178struct LoopIterationSpace final {
4179 /// \brief Condition of the loop.
4180 Expr *PreCond = nullptr;
4181 /// \brief This expression calculates the number of iterations in the loop.
4182 /// It is always possible to calculate it before starting the loop.
4183 Expr *NumIterations = nullptr;
4184 /// \brief The loop counter variable.
4185 Expr *CounterVar = nullptr;
4186 /// \brief Private loop counter variable.
4187 Expr *PrivateCounterVar = nullptr;
4188 /// \brief This is initializer for the initial value of #CounterVar.
4189 Expr *CounterInit = nullptr;
4190 /// \brief This is step for the #CounterVar used to generate its update:
4191 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4192 Expr *CounterStep = nullptr;
4193 /// \brief Should step be subtracted?
4194 bool Subtract = false;
4195 /// \brief Source range of the loop init.
4196 SourceRange InitSrcRange;
4197 /// \brief Source range of the loop condition.
4198 SourceRange CondSrcRange;
4199 /// \brief Source range of the loop increment.
4200 SourceRange IncSrcRange;
4201};
4202
4203} // namespace
4204
4205void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4206 assert(getLangOpts().OpenMP && "OpenMP is not active.")(static_cast <bool> (getLangOpts().OpenMP && "OpenMP is not active."
) ? void (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4206, __extension__ __PRETTY_FUNCTION__))
;
4207 assert(Init && "Expected loop in canonical form.")(static_cast <bool> (Init && "Expected loop in canonical form."
) ? void (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4207, __extension__ __PRETTY_FUNCTION__))
;
4208 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
4209 if (AssociatedLoops > 0 &&
4210 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4211 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4212 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4213 if (auto *D = ISC.GetLoopDecl()) {
4214 auto *VD = dyn_cast<VarDecl>(D);
4215 if (!VD) {
4216 if (auto *Private = IsOpenMPCapturedDecl(D))
4217 VD = Private;
4218 else {
4219 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4220 /*WithInit=*/false);
4221 VD = cast<VarDecl>(Ref->getDecl());
4222 }
4223 }
4224 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
4225 }
4226 }
4227 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
4228 }
4229}
4230
4231/// \brief Called on a for stmt to check and extract its iteration space
4232/// for further processing (such as collapsing).
4233static bool CheckOpenMPIterationSpace(
4234 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4235 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4236 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4237 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4238 LoopIterationSpace &ResultIterSpace,
4239 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4240 // OpenMP [2.6, Canonical Loop Form]
4241 // for (init-expr; test-expr; incr-expr) structured-block
4242 auto *For = dyn_cast_or_null<ForStmt>(S);
4243 if (!For) {
4244 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4245 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4246 << getOpenMPDirectiveName(DKind) << NestedLoopCount
4247 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4248 if (NestedLoopCount > 1) {
4249 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4250 SemaRef.Diag(DSA.getConstructLoc(),
4251 diag::note_omp_collapse_ordered_expr)
4252 << 2 << CollapseLoopCountExpr->getSourceRange()
4253 << OrderedLoopCountExpr->getSourceRange();
4254 else if (CollapseLoopCountExpr)
4255 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4256 diag::note_omp_collapse_ordered_expr)
4257 << 0 << CollapseLoopCountExpr->getSourceRange();
4258 else
4259 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4260 diag::note_omp_collapse_ordered_expr)
4261 << 1 << OrderedLoopCountExpr->getSourceRange();
4262 }
4263 return true;
4264 }
4265 assert(For->getBody())(static_cast <bool> (For->getBody()) ? void (0) : __assert_fail
("For->getBody()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4265, __extension__ __PRETTY_FUNCTION__))
;
4266
4267 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4268
4269 // Check init.
4270 auto Init = For->getInit();
4271 if (ISC.CheckInit(Init))
4272 return true;
4273
4274 bool HasErrors = false;
4275
4276 // Check loop variable's type.
4277 if (auto *LCDecl = ISC.GetLoopDecl()) {
4278 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4279
4280 // OpenMP [2.6, Canonical Loop Form]
4281 // Var is one of the following:
4282 // A variable of signed or unsigned integer type.
4283 // For C++, a variable of a random access iterator type.
4284 // For C, a variable of a pointer type.
4285 auto VarType = LCDecl->getType().getNonReferenceType();
4286 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4287 !VarType->isPointerType() &&
4288 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4289 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4290 << SemaRef.getLangOpts().CPlusPlus;
4291 HasErrors = true;
4292 }
4293
4294 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4295 // a Construct
4296 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4297 // parallel for construct is (are) private.
4298 // The loop iteration variable in the associated for-loop of a simd
4299 // construct with just one associated for-loop is linear with a
4300 // constant-linear-step that is the increment of the associated for-loop.
4301 // Exclude loop var from the list of variables with implicitly defined data
4302 // sharing attributes.
4303 VarsWithImplicitDSA.erase(LCDecl);
4304
4305 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4306 // in a Construct, C/C++].
4307 // The loop iteration variable in the associated for-loop of a simd
4308 // construct with just one associated for-loop may be listed in a linear
4309 // clause with a constant-linear-step that is the increment of the
4310 // associated for-loop.
4311 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4312 // parallel for construct may be listed in a private or lastprivate clause.
4313 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4314 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4315 // declared in the loop and it is predetermined as a private.
4316 auto PredeterminedCKind =
4317 isOpenMPSimdDirective(DKind)
4318 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4319 : OMPC_private;
4320 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4321 DVar.CKind != PredeterminedCKind) ||
4322 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4323 isOpenMPDistributeDirective(DKind)) &&
4324 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4325 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4326 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4327 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4328 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4329 << getOpenMPClauseName(PredeterminedCKind);
4330 if (DVar.RefExpr == nullptr)
4331 DVar.CKind = PredeterminedCKind;
4332 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4333 HasErrors = true;
4334 } else if (LoopDeclRefExpr != nullptr) {
4335 // Make the loop iteration variable private (for worksharing constructs),
4336 // linear (for simd directives with the only one associated loop) or
4337 // lastprivate (for simd directives with several collapsed or ordered
4338 // loops).
4339 if (DVar.CKind == OMPC_unknown)
4340 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4341 [](OpenMPDirectiveKind) -> bool { return true; },
4342 /*FromParent=*/false);
4343 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4344 }
4345
4346 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")(static_cast <bool> (isOpenMPLoopDirective(DKind) &&
"DSA for non-loop vars") ? void (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4346, __extension__ __PRETTY_FUNCTION__))
;
4347
4348 // Check test-expr.
4349 HasErrors |= ISC.CheckCond(For->getCond());
4350
4351 // Check incr-expr.
4352 HasErrors |= ISC.CheckInc(For->getInc());
4353 }
4354
4355 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4356 return HasErrors;
4357
4358 // Build the loop's iteration space representation.
4359 ResultIterSpace.PreCond =
4360 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4361 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4362 DSA.getCurScope(),
4363 (isOpenMPWorksharingDirective(DKind) ||
4364 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4365 Captures);
4366 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4367 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4368 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4369 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4370 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4371 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4372 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4373 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4374
4375 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4376 ResultIterSpace.NumIterations == nullptr ||
4377 ResultIterSpace.CounterVar == nullptr ||
4378 ResultIterSpace.PrivateCounterVar == nullptr ||
4379 ResultIterSpace.CounterInit == nullptr ||
4380 ResultIterSpace.CounterStep == nullptr);
4381
4382 return HasErrors;
4383}
4384
4385/// \brief Build 'VarRef = Start.
4386static ExprResult
4387BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4388 ExprResult Start,
4389 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4390 // Build 'VarRef = Start.
4391 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4392 if (!NewStart.isUsable())
4393 return ExprError();
4394 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4395 VarRef.get()->getType())) {
4396 NewStart = SemaRef.PerformImplicitConversion(
4397 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4398 /*AllowExplicit=*/true);
4399 if (!NewStart.isUsable())
4400 return ExprError();
4401 }
4402
4403 auto Init =
4404 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4405 return Init;
4406}
4407
4408/// \brief Build 'VarRef = Start + Iter * Step'.
4409static ExprResult
4410BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc,
4411 ExprResult VarRef, ExprResult Start, ExprResult Iter,
4412 ExprResult Step, bool Subtract,
4413 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4414 // Add parentheses (for debugging purposes only).
4415 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4416 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4417 !Step.isUsable())
4418 return ExprError();
4419
4420 ExprResult NewStep = Step;
4421 if (Captures)
4422 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4423 if (NewStep.isInvalid())
4424 return ExprError();
4425 ExprResult Update =
4426 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4427 if (!Update.isUsable())
4428 return ExprError();
4429
4430 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4431 // 'VarRef = Start (+|-) Iter * Step'.
4432 ExprResult NewStart = Start;
4433 if (Captures)
4434 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4435 if (NewStart.isInvalid())
4436 return ExprError();
4437
4438 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4439 ExprResult SavedUpdate = Update;
4440 ExprResult UpdateVal;
4441 if (VarRef.get()->getType()->isOverloadableType() ||
4442 NewStart.get()->getType()->isOverloadableType() ||
4443 Update.get()->getType()->isOverloadableType()) {
4444 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4445 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4446 Update =
4447 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4448 if (Update.isUsable()) {
4449 UpdateVal =
4450 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4451 VarRef.get(), SavedUpdate.get());
4452 if (UpdateVal.isUsable()) {
4453 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4454 UpdateVal.get());
4455 }
4456 }
4457 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4458 }
4459
4460 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4461 if (!Update.isUsable() || !UpdateVal.isUsable()) {
4462 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4463 NewStart.get(), SavedUpdate.get());
4464 if (!Update.isUsable())
4465 return ExprError();
4466
4467 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4468 VarRef.get()->getType())) {
4469 Update = SemaRef.PerformImplicitConversion(
4470 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4471 if (!Update.isUsable())
4472 return ExprError();
4473 }
4474
4475 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4476 }
4477 return Update;
4478}
4479
4480/// \brief Convert integer expression \a E to make it have at least \a Bits
4481/// bits.
4482static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4483 if (E == nullptr)
4484 return ExprError();
4485 auto &C = SemaRef.Context;
4486 QualType OldType = E->getType();
4487 unsigned HasBits = C.getTypeSize(OldType);
4488 if (HasBits >= Bits)
4489 return ExprResult(E);
4490 // OK to convert to signed, because new type has more bits than old.
4491 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4492 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4493 true);
4494}
4495
4496/// \brief Check if the given expression \a E is a constant integer that fits
4497/// into \a Bits bits.
4498static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4499 if (E == nullptr)
4500 return false;
4501 llvm::APSInt Result;
4502 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4503 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4504 return false;
4505}
4506
4507/// Build preinits statement for the given declarations.
4508static Stmt *buildPreInits(ASTContext &Context,
4509 MutableArrayRef<Decl *> PreInits) {
4510 if (!PreInits.empty()) {
4511 return new (Context) DeclStmt(
4512 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4513 SourceLocation(), SourceLocation());
4514 }
4515 return nullptr;
4516}
4517
4518/// Build preinits statement for the given declarations.
4519static Stmt *
4520buildPreInits(ASTContext &Context,
4521 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4522 if (!Captures.empty()) {
4523 SmallVector<Decl *, 16> PreInits;
4524 for (auto &Pair : Captures)
4525 PreInits.push_back(Pair.second->getDecl());
4526 return buildPreInits(Context, PreInits);
4527 }
4528 return nullptr;
4529}
4530
4531/// Build postupdate expression for the given list of postupdates expressions.
4532static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4533 Expr *PostUpdate = nullptr;
4534 if (!PostUpdates.empty()) {
4535 for (auto *E : PostUpdates) {
4536 Expr *ConvE = S.BuildCStyleCastExpr(
4537 E->getExprLoc(),
4538 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4539 E->getExprLoc(), E)
4540 .get();
4541 PostUpdate = PostUpdate
4542 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4543 PostUpdate, ConvE)
4544 .get()
4545 : ConvE;
4546 }
4547 }
4548 return PostUpdate;
4549}
4550
4551/// \brief Called on a for stmt to check itself and nested loops (if any).
4552/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4553/// number of collapsed loops otherwise.
4554static unsigned
4555CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4556 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4557 DSAStackTy &DSA,
4558 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4559 OMPLoopDirective::HelperExprs &Built) {
4560 unsigned NestedLoopCount = 1;
4561 if (CollapseLoopCountExpr) {
4562 // Found 'collapse' clause - calculate collapse number.
4563 llvm::APSInt Result;
4564 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4565 NestedLoopCount = Result.getLimitedValue();
4566 }
4567 if (OrderedLoopCountExpr) {
4568 // Found 'ordered' clause - calculate collapse number.
4569 llvm::APSInt Result;
4570 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4571 if (Result.getLimitedValue() < NestedLoopCount) {
4572 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4573 diag::err_omp_wrong_ordered_loop_count)
4574 << OrderedLoopCountExpr->getSourceRange();
4575 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4576 diag::note_collapse_loop_count)
4577 << CollapseLoopCountExpr->getSourceRange();
4578 }
4579 NestedLoopCount = Result.getLimitedValue();
4580 }
4581 }
4582 // This is helper routine for loop directives (e.g., 'for', 'simd',
4583 // 'for simd', etc.).
4584 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4585 SmallVector<LoopIterationSpace, 4> IterSpaces;
4586 IterSpaces.resize(NestedLoopCount);
4587 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4588 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4589 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4590 NestedLoopCount, CollapseLoopCountExpr,
4591 OrderedLoopCountExpr, VarsWithImplicitDSA,
4592 IterSpaces[Cnt], Captures))
4593 return 0;
4594 // Move on to the next nested for loop, or to the loop body.
4595 // OpenMP [2.8.1, simd construct, Restrictions]
4596 // All loops associated with the construct must be perfectly nested; that
4597 // is, there must be no intervening code nor any OpenMP directive between
4598 // any two loops.
4599 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4600 }
4601
4602 Built.clear(/* size */ NestedLoopCount);
4603
4604 if (SemaRef.CurContext->isDependentContext())
4605 return NestedLoopCount;
4606
4607 // An example of what is generated for the following code:
4608 //
4609 // #pragma omp simd collapse(2) ordered(2)
4610 // for (i = 0; i < NI; ++i)
4611 // for (k = 0; k < NK; ++k)
4612 // for (j = J0; j < NJ; j+=2) {
4613 // <loop body>
4614 // }
4615 //
4616 // We generate the code below.
4617 // Note: the loop body may be outlined in CodeGen.
4618 // Note: some counters may be C++ classes, operator- is used to find number of
4619 // iterations and operator+= to calculate counter value.
4620 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4621 // or i64 is currently supported).
4622 //
4623 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4624 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4625 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4626 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4627 // // similar updates for vars in clauses (e.g. 'linear')
4628 // <loop body (using local i and j)>
4629 // }
4630 // i = NI; // assign final values of counters
4631 // j = NJ;
4632 //
4633
4634 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4635 // the iteration counts of the collapsed for loops.
4636 // Precondition tests if there is at least one iteration (all conditions are
4637 // true).
4638 auto PreCond = ExprResult(IterSpaces[0].PreCond);
4639 auto N0 = IterSpaces[0].NumIterations;
4640 ExprResult LastIteration32 = WidenIterationCount(
4641 32 /* Bits */, SemaRef
4642 .PerformImplicitConversion(
4643 N0->IgnoreImpCasts(), N0->getType(),
4644 Sema::AA_Converting, /*AllowExplicit=*/true)
4645 .get(),
4646 SemaRef);
4647 ExprResult LastIteration64 = WidenIterationCount(
4648 64 /* Bits */, SemaRef
4649 .PerformImplicitConversion(
4650 N0->IgnoreImpCasts(), N0->getType(),
4651 Sema::AA_Converting, /*AllowExplicit=*/true)
4652 .get(),
4653 SemaRef);
4654
4655 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4656 return NestedLoopCount;
4657
4658 auto &C = SemaRef.Context;
4659 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4660
4661 Scope *CurScope = DSA.getCurScope();
4662 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4663 if (PreCond.isUsable()) {
4664 PreCond =
4665 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4666 PreCond.get(), IterSpaces[Cnt].PreCond);
4667 }
4668 auto N = IterSpaces[Cnt].NumIterations;
4669 SourceLocation Loc = N->getExprLoc();
4670 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4671 if (LastIteration32.isUsable())
4672 LastIteration32 = SemaRef.BuildBinOp(
4673 CurScope, Loc, BO_Mul, LastIteration32.get(),
4674 SemaRef
4675 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4676 Sema::AA_Converting,
4677 /*AllowExplicit=*/true)
4678 .get());
4679 if (LastIteration64.isUsable())
4680 LastIteration64 = SemaRef.BuildBinOp(
4681 CurScope, Loc, BO_Mul, LastIteration64.get(),
4682 SemaRef
4683 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4684 Sema::AA_Converting,
4685 /*AllowExplicit=*/true)
4686 .get());
4687 }
4688
4689 // Choose either the 32-bit or 64-bit version.
4690 ExprResult LastIteration = LastIteration64;
4691 if (LastIteration32.isUsable() &&
4692 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4693 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4694 FitsInto(
4695 32 /* Bits */,
4696 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4697 LastIteration64.get(), SemaRef)))
4698 LastIteration = LastIteration32;
4699 QualType VType = LastIteration.get()->getType();
4700 QualType RealVType = VType;
4701 QualType StrideVType = VType;
4702 if (isOpenMPTaskLoopDirective(DKind)) {
4703 VType =
4704 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4705 StrideVType =
4706 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4707 }
4708
4709 if (!LastIteration.isUsable())
4710 return 0;
4711
4712 // Save the number of iterations.
4713 ExprResult NumIterations = LastIteration;
4714 {
4715 LastIteration = SemaRef.BuildBinOp(
4716 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4717 LastIteration.get(),
4718 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4719 if (!LastIteration.isUsable())
4720 return 0;
4721 }
4722
4723 // Calculate the last iteration number beforehand instead of doing this on
4724 // each iteration. Do not do this if the number of iterations may be kfold-ed.
4725 llvm::APSInt Result;
4726 bool IsConstant =
4727 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4728 ExprResult CalcLastIteration;
4729 if (!IsConstant) {
4730 ExprResult SaveRef =
4731 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4732 LastIteration = SaveRef;
4733
4734 // Prepare SaveRef + 1.
4735 NumIterations = SemaRef.BuildBinOp(
4736 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4737 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4738 if (!NumIterations.isUsable())
4739 return 0;
4740 }
4741
4742 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4743
4744 // Build variables passed into runtime, necessary for worksharing directives.
4745 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4746 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4747 isOpenMPDistributeDirective(DKind)) {
4748 // Lower bound variable, initialized with zero.
4749 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4750 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4751 SemaRef.AddInitializerToDecl(LBDecl,
4752 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4753 /*DirectInit*/ false);
4754
4755 // Upper bound variable, initialized with last iteration number.
4756 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4757 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4758 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4759 /*DirectInit*/ false);
4760
4761 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4762 // This will be used to implement clause 'lastprivate'.
4763 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4764 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4765 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4766 SemaRef.AddInitializerToDecl(ILDecl,
4767 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4768 /*DirectInit*/ false);
4769
4770 // Stride variable returned by runtime (we initialize it to 1 by default).
4771 VarDecl *STDecl =
4772 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4773 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4774 SemaRef.AddInitializerToDecl(STDecl,
4775 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4776 /*DirectInit*/ false);
4777
4778 // Build expression: UB = min(UB, LastIteration)
4779 // It is necessary for CodeGen of directives with static scheduling.
4780 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4781 UB.get(), LastIteration.get());
4782 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4783 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4784 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4785 CondOp.get());
4786 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4787
4788 // If we have a combined directive that combines 'distribute', 'for' or
4789 // 'simd' we need to be able to access the bounds of the schedule of the
4790 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4791 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4792 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4793
4794 // Lower bound variable, initialized with zero.
4795 VarDecl *CombLBDecl =
4796 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4797 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4798 SemaRef.AddInitializerToDecl(
4799 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4800 /*DirectInit*/ false);
4801
4802 // Upper bound variable, initialized with last iteration number.
4803 VarDecl *CombUBDecl =
4804 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4805 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4806 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4807 /*DirectInit*/ false);
4808
4809 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4810 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4811 ExprResult CombCondOp =
4812 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4813 LastIteration.get(), CombUB.get());
4814 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4815 CombCondOp.get());
4816 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4817
4818 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4819 // We expect to have at least 2 more parameters than the 'parallel'
4820 // directive does - the lower and upper bounds of the previous schedule.
4821 assert(CD->getNumParams() >= 4 &&(static_cast <bool> (CD->getNumParams() >= 4 &&
"Unexpected number of parameters in loop combined directive"
) ? void (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4822, __extension__ __PRETTY_FUNCTION__))
4822 "Unexpected number of parameters in loop combined directive")(static_cast <bool> (CD->getNumParams() >= 4 &&
"Unexpected number of parameters in loop combined directive"
) ? void (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4822, __extension__ __PRETTY_FUNCTION__))
;
4823
4824 // Set the proper type for the bounds given what we learned from the
4825 // enclosed loops.
4826 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4827 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4828
4829 // Previous lower and upper bounds are obtained from the region
4830 // parameters.
4831 PrevLB =
4832 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4833 PrevUB =
4834 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4835 }
4836 }
4837
4838 // Build the iteration variable and its initialization before loop.
4839 ExprResult IV;
4840 ExprResult Init, CombInit;
4841 {
4842 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4843 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4844 Expr *RHS =
4845 (isOpenMPWorksharingDirective(DKind) ||
4846 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4847 ? LB.get()
4848 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4849 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4850 Init = SemaRef.ActOnFinishFullExpr(Init.get());
4851
4852 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4853 Expr *CombRHS =
4854 (isOpenMPWorksharingDirective(DKind) ||
4855 isOpenMPTaskLoopDirective(DKind) ||
4856 isOpenMPDistributeDirective(DKind))
4857 ? CombLB.get()
4858 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4859 CombInit =
4860 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4861 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4862 }
4863 }
4864
4865 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4866 SourceLocation CondLoc = AStmt->getLocStart();
4867 ExprResult Cond =
4868 (isOpenMPWorksharingDirective(DKind) ||
4869 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4870 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4871 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4872 NumIterations.get());
4873 ExprResult CombCond;
4874 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4875 CombCond =
4876 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4877 }
4878 // Loop increment (IV = IV + 1)
4879 SourceLocation IncLoc = AStmt->getLocStart();
4880 ExprResult Inc =
4881 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4882 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4883 if (!Inc.isUsable())
4884 return 0;
4885 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4886 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4887 if (!Inc.isUsable())
4888 return 0;
4889
4890 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4891 // Used for directives with static scheduling.
4892 // In combined construct, add combined version that use CombLB and CombUB
4893 // base variables for the update
4894 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4895 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4896 isOpenMPDistributeDirective(DKind)) {
4897 // LB + ST
4898 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4899 if (!NextLB.isUsable())
4900 return 0;
4901 // LB = LB + ST
4902 NextLB =
4903 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4904 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4905 if (!NextLB.isUsable())
4906 return 0;
4907 // UB + ST
4908 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4909 if (!NextUB.isUsable())
4910 return 0;
4911 // UB = UB + ST
4912 NextUB =
4913 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4914 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4915 if (!NextUB.isUsable())
4916 return 0;
4917 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4918 CombNextLB =
4919 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4920 if (!NextLB.isUsable())
4921 return 0;
4922 // LB = LB + ST
4923 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4924 CombNextLB.get());
4925 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4926 if (!CombNextLB.isUsable())
4927 return 0;
4928 // UB + ST
4929 CombNextUB =
4930 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4931 if (!CombNextUB.isUsable())
4932 return 0;
4933 // UB = UB + ST
4934 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4935 CombNextUB.get());
4936 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4937 if (!CombNextUB.isUsable())
4938 return 0;
4939 }
4940 }
4941
4942 // Create increment expression for distribute loop when combined in a same
4943 // directive with for as IV = IV + ST; ensure upper bound expression based
4944 // on PrevUB instead of NumIterations - used to implement 'for' when found
4945 // in combination with 'distribute', like in 'distribute parallel for'
4946 SourceLocation DistIncLoc = AStmt->getLocStart();
4947 ExprResult DistCond, DistInc, PrevEUB;
4948 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4949 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4950 assert(DistCond.isUsable() && "distribute cond expr was not built")(static_cast <bool> (DistCond.isUsable() && "distribute cond expr was not built"
) ? void (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4950, __extension__ __PRETTY_FUNCTION__))
;
4951
4952 DistInc =
4953 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4954 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast <bool> (DistInc.isUsable() && "distribute inc expr was not built"
) ? void (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4954, __extension__ __PRETTY_FUNCTION__))
;
4955 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4956 DistInc.get());
4957 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4958 assert(DistInc.isUsable() && "distribute inc expr was not built")(static_cast <bool> (DistInc.isUsable() && "distribute inc expr was not built"
) ? void (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4958, __extension__ __PRETTY_FUNCTION__))
;
4959
4960 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4961 // construct
4962 SourceLocation DistEUBLoc = AStmt->getLocStart();
4963 ExprResult IsUBGreater =
4964 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4965 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4966 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4967 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4968 CondOp.get());
4969 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4970 }
4971
4972 // Build updates and final values of the loop counters.
4973 bool HasErrors = false;
4974 Built.Counters.resize(NestedLoopCount);
4975 Built.Inits.resize(NestedLoopCount);
4976 Built.Updates.resize(NestedLoopCount);
4977 Built.Finals.resize(NestedLoopCount);
4978 SmallVector<Expr *, 4> LoopMultipliers;
4979 {
4980 ExprResult Div;
4981 // Go from inner nested loop to outer.
4982 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4983 LoopIterationSpace &IS = IterSpaces[Cnt];
4984 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4985 // Build: Iter = (IV / Div) % IS.NumIters
4986 // where Div is product of previous iterations' IS.NumIters.
4987 ExprResult Iter;
4988 if (Div.isUsable()) {
4989 Iter =
4990 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4991 } else {
4992 Iter = IV;
4993 assert((Cnt == (int)NestedLoopCount - 1) &&(static_cast <bool> ((Cnt == (int)NestedLoopCount - 1) &&
"unusable div expected on first iteration only") ? void (0) :
__assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4994, __extension__ __PRETTY_FUNCTION__))
4994 "unusable div expected on first iteration only")(static_cast <bool> ((Cnt == (int)NestedLoopCount - 1) &&
"unusable div expected on first iteration only") ? void (0) :
__assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4994, __extension__ __PRETTY_FUNCTION__))
;
4995 }
4996
4997 if (Cnt != 0 && Iter.isUsable())
4998 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4999 IS.NumIterations);
5000 if (!Iter.isUsable()) {
5001 HasErrors = true;
5002 break;
5003 }
5004
5005 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5006 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5007 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
5008 IS.CounterVar->getExprLoc(),
5009 /*RefersToCapture=*/true);
5010 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5011 IS.CounterInit, Captures);
5012 if (!Init.isUsable()) {
5013 HasErrors = true;
5014 break;
5015 }
5016 ExprResult Update = BuildCounterUpdate(
5017 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5018 IS.CounterStep, IS.Subtract, &Captures);
5019 if (!Update.isUsable()) {
5020 HasErrors = true;
5021 break;
5022 }
5023
5024 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5025 ExprResult Final = BuildCounterUpdate(
5026 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5027 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5028 if (!Final.isUsable()) {
5029 HasErrors = true;
5030 break;
5031 }
5032
5033 // Build Div for the next iteration: Div <- Div * IS.NumIters
5034 if (Cnt != 0) {
5035 if (Div.isUnset())
5036 Div = IS.NumIterations;
5037 else
5038 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
5039 IS.NumIterations);
5040
5041 // Add parentheses (for debugging purposes only).
5042 if (Div.isUsable())
5043 Div = tryBuildCapture(SemaRef, Div.get(), Captures);
5044 if (!Div.isUsable()) {
5045 HasErrors = true;
5046 break;
5047 }
5048 LoopMultipliers.push_back(Div.get());
5049 }
5050 if (!Update.isUsable() || !Final.isUsable()) {
5051 HasErrors = true;
5052 break;
5053 }
5054 // Save results
5055 Built.Counters[Cnt] = IS.CounterVar;
5056 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5057 Built.Inits[Cnt] = Init.get();
5058 Built.Updates[Cnt] = Update.get();
5059 Built.Finals[Cnt] = Final.get();
5060 }
5061 }
5062
5063 if (HasErrors)
5064 return 0;
5065
5066 // Save results
5067 Built.IterationVarRef = IV.get();
5068 Built.LastIteration = LastIteration.get();
5069 Built.NumIterations = NumIterations.get();
5070 Built.CalcLastIteration =
5071 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5072 Built.PreCond = PreCond.get();
5073 Built.PreInits = buildPreInits(C, Captures);
5074 Built.Cond = Cond.get();
5075 Built.Init = Init.get();
5076 Built.Inc = Inc.get();
5077 Built.LB = LB.get();
5078 Built.UB = UB.get();
5079 Built.IL = IL.get();
5080 Built.ST = ST.get();
5081 Built.EUB = EUB.get();
5082 Built.NLB = NextLB.get();
5083 Built.NUB = NextUB.get();
5084 Built.PrevLB = PrevLB.get();
5085 Built.PrevUB = PrevUB.get();
5086 Built.DistInc = DistInc.get();
5087 Built.PrevEUB = PrevEUB.get();
5088 Built.DistCombinedFields.LB = CombLB.get();
5089 Built.DistCombinedFields.UB = CombUB.get();
5090 Built.DistCombinedFields.EUB = CombEUB.get();
5091 Built.DistCombinedFields.Init = CombInit.get();
5092 Built.DistCombinedFields.Cond = CombCond.get();
5093 Built.DistCombinedFields.NLB = CombNextLB.get();
5094 Built.DistCombinedFields.NUB = CombNextUB.get();
5095
5096 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
5097 // Fill data for doacross depend clauses.
5098 for (auto Pair : DSA.getDoacrossDependClauses()) {
5099 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5100 Pair.first->setCounterValue(CounterVal);
5101 else {
5102 if (NestedLoopCount != Pair.second.size() ||
5103 NestedLoopCount != LoopMultipliers.size() + 1) {
5104 // Erroneous case - clause has some problems.
5105 Pair.first->setCounterValue(CounterVal);
5106 continue;
5107 }
5108 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink)(static_cast <bool> (Pair.first->getDependencyKind()
== OMPC_DEPEND_sink) ? void (0) : __assert_fail ("Pair.first->getDependencyKind() == OMPC_DEPEND_sink"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5108, __extension__ __PRETTY_FUNCTION__))
;
5109 auto I = Pair.second.rbegin();
5110 auto IS = IterSpaces.rbegin();
5111 auto ILM = LoopMultipliers.rbegin();
5112 Expr *UpCounterVal = CounterVal;
5113 Expr *Multiplier = nullptr;
5114 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5115 if (I->first) {
5116 assert(IS->CounterStep)(static_cast <bool> (IS->CounterStep) ? void (0) : __assert_fail
("IS->CounterStep", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5116, __extension__ __PRETTY_FUNCTION__))
;
5117 Expr *NormalizedOffset =
5118 SemaRef
5119 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5120 I->first, IS->CounterStep)
5121 .get();
5122 if (Multiplier) {
5123 NormalizedOffset =
5124 SemaRef
5125 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5126 NormalizedOffset, Multiplier)
5127 .get();
5128 }
5129 assert(I->second == OO_Plus || I->second == OO_Minus)(static_cast <bool> (I->second == OO_Plus || I->second
== OO_Minus) ? void (0) : __assert_fail ("I->second == OO_Plus || I->second == OO_Minus"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5129, __extension__ __PRETTY_FUNCTION__))
;
5130 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5131 UpCounterVal = SemaRef
5132 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5133 UpCounterVal, NormalizedOffset)
5134 .get();
5135 }
5136 Multiplier = *ILM;
5137 ++I;
5138 ++IS;
5139 ++ILM;
5140 }
5141 Pair.first->setCounterValue(UpCounterVal);
5142 }
5143 }
5144
5145 return NestedLoopCount;
5146}
5147
5148static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5149 auto CollapseClauses =
5150 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5151 if (CollapseClauses.begin() != CollapseClauses.end())
5152 return (*CollapseClauses.begin())->getNumForLoops();
5153 return nullptr;
5154}
5155
5156static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5157 auto OrderedClauses =
5158 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5159 if (OrderedClauses.begin() != OrderedClauses.end())
5160 return (*OrderedClauses.begin())->getNumForLoops();
5161 return nullptr;
5162}
5163
5164static bool checkSimdlenSafelenSpecified(Sema &S,
5165 const ArrayRef<OMPClause *> Clauses) {
5166 OMPSafelenClause *Safelen = nullptr;
5167 OMPSimdlenClause *Simdlen = nullptr;
5168
5169 for (auto *Clause : Clauses) {
5170 if (Clause->getClauseKind() == OMPC_safelen)
5171 Safelen = cast<OMPSafelenClause>(Clause);
5172 else if (Clause->getClauseKind() == OMPC_simdlen)
5173 Simdlen = cast<OMPSimdlenClause>(Clause);
5174 if (Safelen && Simdlen)
5175 break;
5176 }
5177
5178 if (Simdlen && Safelen) {
5179 llvm::APSInt SimdlenRes, SafelenRes;
5180 auto SimdlenLength = Simdlen->getSimdlen();
5181 auto SafelenLength = Safelen->getSafelen();
5182 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5183 SimdlenLength->isInstantiationDependent() ||
5184 SimdlenLength->containsUnexpandedParameterPack())
5185 return false;
5186 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5187 SafelenLength->isInstantiationDependent() ||
5188 SafelenLength->containsUnexpandedParameterPack())
5189 return false;
5190 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5191 SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5192 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5193 // If both simdlen and safelen clauses are specified, the value of the
5194 // simdlen parameter must be less than or equal to the value of the safelen
5195 // parameter.
5196 if (SimdlenRes > SafelenRes) {
5197 S.Diag(SimdlenLength->getExprLoc(),
5198 diag::err_omp_wrong_simdlen_safelen_values)
5199 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5200 return true;
5201 }
5202 }
5203 return false;
5204}
5205
5206StmtResult Sema::ActOnOpenMPSimdDirective(
5207 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5208 SourceLocation EndLoc,
5209 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5210 if (!AStmt)
5211 return StmtError();
5212
5213 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5213, __extension__ __PRETTY_FUNCTION__))
;
5214 OMPLoopDirective::HelperExprs B;
5215 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5216 // define the nested loops number.
5217 unsigned NestedLoopCount = CheckOpenMPLoop(
5218 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5219 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5220 if (NestedLoopCount == 0)
5221 return StmtError();
5222
5223 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __extension__ __PRETTY_FUNCTION__))
5224 "omp simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5224, __extension__ __PRETTY_FUNCTION__))
;
5225
5226 if (!CurContext->isDependentContext()) {
5227 // Finalize the clauses that need pre-built expressions for CodeGen.
5228 for (auto C : Clauses) {
5229 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5230 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5231 B.NumIterations, *this, CurScope,
5232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5233 return StmtError();
5234 }
5235 }
5236
5237 if (checkSimdlenSafelenSpecified(*this, Clauses))
5238 return StmtError();
5239
5240 getCurFunction()->setHasBranchProtectedScope();
5241 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5242 Clauses, AStmt, B);
5243}
5244
5245StmtResult Sema::ActOnOpenMPForDirective(
5246 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5247 SourceLocation EndLoc,
5248 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5249 if (!AStmt)
5250 return StmtError();
5251
5252 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5252, __extension__ __PRETTY_FUNCTION__))
;
5253 OMPLoopDirective::HelperExprs B;
5254 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5255 // define the nested loops number.
5256 unsigned NestedLoopCount = CheckOpenMPLoop(
5257 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5258 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5259 if (NestedLoopCount == 0)
5260 return StmtError();
5261
5262 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5263, __extension__ __PRETTY_FUNCTION__))
5263 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5263, __extension__ __PRETTY_FUNCTION__))
;
5264
5265 if (!CurContext->isDependentContext()) {
5266 // Finalize the clauses that need pre-built expressions for CodeGen.
5267 for (auto C : Clauses) {
5268 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5269 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5270 B.NumIterations, *this, CurScope,
5271 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5272 return StmtError();
5273 }
5274 }
5275
5276 getCurFunction()->setHasBranchProtectedScope();
5277 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5278 Clauses, AStmt, B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5279}
5280
5281StmtResult Sema::ActOnOpenMPForSimdDirective(
5282 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5283 SourceLocation EndLoc,
5284 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5285 if (!AStmt)
5286 return StmtError();
5287
5288 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5288, __extension__ __PRETTY_FUNCTION__))
;
5289 OMPLoopDirective::HelperExprs B;
5290 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5291 // define the nested loops number.
5292 unsigned NestedLoopCount =
5293 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5294 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5295 VarsWithImplicitDSA, B);
5296 if (NestedLoopCount == 0)
5297 return StmtError();
5298
5299 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5300, __extension__ __PRETTY_FUNCTION__))
5300 "omp for simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5300, __extension__ __PRETTY_FUNCTION__))
;
5301
5302 if (!CurContext->isDependentContext()) {
5303 // Finalize the clauses that need pre-built expressions for CodeGen.
5304 for (auto C : Clauses) {
5305 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5306 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5307 B.NumIterations, *this, CurScope,
5308 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5309 return StmtError();
5310 }
5311 }
5312
5313 if (checkSimdlenSafelenSpecified(*this, Clauses))
5314 return StmtError();
5315
5316 getCurFunction()->setHasBranchProtectedScope();
5317 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5318 Clauses, AStmt, B);
5319}
5320
5321StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5322 Stmt *AStmt,
5323 SourceLocation StartLoc,
5324 SourceLocation EndLoc) {
5325 if (!AStmt)
5326 return StmtError();
5327
5328 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5328, __extension__ __PRETTY_FUNCTION__))
;
5329 auto BaseStmt = AStmt;
5330 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5331 BaseStmt = CS->getCapturedStmt();
5332 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5333 auto S = C->children();
5334 if (S.begin() == S.end())
5335 return StmtError();
5336 // All associated statements must be '#pragma omp section' except for
5337 // the first one.
5338 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5339 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5340 if (SectionStmt)
5341 Diag(SectionStmt->getLocStart(),
5342 diag::err_omp_sections_substmt_not_section);
5343 return StmtError();
5344 }
5345 cast<OMPSectionDirective>(SectionStmt)
5346 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5347 }
5348 } else {
5349 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5350 return StmtError();
5351 }
5352
5353 getCurFunction()->setHasBranchProtectedScope();
5354
5355 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5356 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5357}
5358
5359StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5360 SourceLocation StartLoc,
5361 SourceLocation EndLoc) {
5362 if (!AStmt)
5363 return StmtError();
5364
5365 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5365, __extension__ __PRETTY_FUNCTION__))
;
5366
5367 getCurFunction()->setHasBranchProtectedScope();
5368 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5369
5370 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5371 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5372}
5373
5374StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5375 Stmt *AStmt,
5376 SourceLocation StartLoc,
5377 SourceLocation EndLoc) {
5378 if (!AStmt)
5379 return StmtError();
5380
5381 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5381, __extension__ __PRETTY_FUNCTION__))
;
5382
5383 getCurFunction()->setHasBranchProtectedScope();
5384
5385 // OpenMP [2.7.3, single Construct, Restrictions]
5386 // The copyprivate clause must not be used with the nowait clause.
5387 OMPClause *Nowait = nullptr;
5388 OMPClause *Copyprivate = nullptr;
5389 for (auto *Clause : Clauses) {
5390 if (Clause->getClauseKind() == OMPC_nowait)
5391 Nowait = Clause;
5392 else if (Clause->getClauseKind() == OMPC_copyprivate)
5393 Copyprivate = Clause;
5394 if (Copyprivate && Nowait) {
5395 Diag(Copyprivate->getLocStart(),
5396 diag::err_omp_single_copyprivate_with_nowait);
5397 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5398 return StmtError();
5399 }
5400 }
5401
5402 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5403}
5404
5405StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5406 SourceLocation StartLoc,
5407 SourceLocation EndLoc) {
5408 if (!AStmt)
5409 return StmtError();
5410
5411 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5411, __extension__ __PRETTY_FUNCTION__))
;
5412
5413 getCurFunction()->setHasBranchProtectedScope();
5414
5415 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5416}
5417
5418StmtResult Sema::ActOnOpenMPCriticalDirective(
5419 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5420 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5421 if (!AStmt)
5422 return StmtError();
5423
5424 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5424, __extension__ __PRETTY_FUNCTION__))
;
5425
5426 bool ErrorFound = false;
5427 llvm::APSInt Hint;
5428 SourceLocation HintLoc;
5429 bool DependentHint = false;
5430 for (auto *C : Clauses) {
5431 if (C->getClauseKind() == OMPC_hint) {
5432 if (!DirName.getName()) {
5433 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5434 ErrorFound = true;
5435 }
5436 Expr *E = cast<OMPHintClause>(C)->getHint();
5437 if (E->isTypeDependent() || E->isValueDependent() ||
5438 E->isInstantiationDependent())
5439 DependentHint = true;
5440 else {
5441 Hint = E->EvaluateKnownConstInt(Context);
5442 HintLoc = C->getLocStart();
5443 }
5444 }
5445 }
5446 if (ErrorFound)
5447 return StmtError();
5448 auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
5449 if (Pair.first && DirName.getName() && !DependentHint) {
5450 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5451 Diag(StartLoc, diag::err_omp_critical_with_hint);
5452 if (HintLoc.isValid()) {
5453 Diag(HintLoc, diag::note_omp_critical_hint_here)
5454 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5455 } else
5456 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5457 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5458 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5459 << 1
5460 << C->getHint()->EvaluateKnownConstInt(Context).toString(
5461 /*Radix=*/10, /*Signed=*/false);
5462 } else
5463 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5464 }
5465 }
5466
5467 getCurFunction()->setHasBranchProtectedScope();
5468
5469 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5470 Clauses, AStmt);
5471 if (!Pair.first && DirName.getName() && !DependentHint)
5472 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
5473 return Dir;
5474}
5475
5476StmtResult Sema::ActOnOpenMPParallelForDirective(
5477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5478 SourceLocation EndLoc,
5479 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5480 if (!AStmt)
5481 return StmtError();
5482
5483 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5484 // 1.2.2 OpenMP Language Terminology
5485 // Structured block - An executable statement with a single entry at the
5486 // top and a single exit at the bottom.
5487 // The point of exit cannot be a branch out of the structured block.
5488 // longjmp() and throw() must not violate the entry/exit criteria.
5489 CS->getCapturedDecl()->setNothrow();
5490
5491 OMPLoopDirective::HelperExprs B;
5492 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5493 // define the nested loops number.
5494 unsigned NestedLoopCount =
5495 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5496 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5497 VarsWithImplicitDSA, B);
5498 if (NestedLoopCount == 0)
5499 return StmtError();
5500
5501 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5502, __extension__ __PRETTY_FUNCTION__))
5502 "omp parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5502, __extension__ __PRETTY_FUNCTION__))
;
5503
5504 if (!CurContext->isDependentContext()) {
5505 // Finalize the clauses that need pre-built expressions for CodeGen.
5506 for (auto C : Clauses) {
5507 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5508 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5509 B.NumIterations, *this, CurScope,
5510 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5511 return StmtError();
5512 }
5513 }
5514
5515 getCurFunction()->setHasBranchProtectedScope();
5516 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5517 NestedLoopCount, Clauses, AStmt, B,
5518 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5519}
5520
5521StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
5522 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5523 SourceLocation EndLoc,
5524 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5525 if (!AStmt)
5526 return StmtError();
5527
5528 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5529 // 1.2.2 OpenMP Language Terminology
5530 // Structured block - An executable statement with a single entry at the
5531 // top and a single exit at the bottom.
5532 // The point of exit cannot be a branch out of the structured block.
5533 // longjmp() and throw() must not violate the entry/exit criteria.
5534 CS->getCapturedDecl()->setNothrow();
5535
5536 OMPLoopDirective::HelperExprs B;
5537 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5538 // define the nested loops number.
5539 unsigned NestedLoopCount =
5540 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5541 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5542 VarsWithImplicitDSA, B);
5543 if (NestedLoopCount == 0)
5544 return StmtError();
5545
5546 if (!CurContext->isDependentContext()) {
5547 // Finalize the clauses that need pre-built expressions for CodeGen.
5548 for (auto C : Clauses) {
5549 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5550 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5551 B.NumIterations, *this, CurScope,
5552 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5553 return StmtError();
5554 }
5555 }
5556
5557 if (checkSimdlenSafelenSpecified(*this, Clauses))
5558 return StmtError();
5559
5560 getCurFunction()->setHasBranchProtectedScope();
5561 return OMPParallelForSimdDirective::Create(
5562 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5563}
5564
5565StmtResult
5566Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
5567 Stmt *AStmt, SourceLocation StartLoc,
5568 SourceLocation EndLoc) {
5569 if (!AStmt)
5570 return StmtError();
5571
5572 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5572, __extension__ __PRETTY_FUNCTION__))
;
5573 auto BaseStmt = AStmt;
5574 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5575 BaseStmt = CS->getCapturedStmt();
5576 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5577 auto S = C->children();
5578 if (S.begin() == S.end())
5579 return StmtError();
5580 // All associated statements must be '#pragma omp section' except for
5581 // the first one.
5582 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5583 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5584 if (SectionStmt)
5585 Diag(SectionStmt->getLocStart(),
5586 diag::err_omp_parallel_sections_substmt_not_section);
5587 return StmtError();
5588 }
5589 cast<OMPSectionDirective>(SectionStmt)
5590 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5591 }
5592 } else {
5593 Diag(AStmt->getLocStart(),
5594 diag::err_omp_parallel_sections_not_compound_stmt);
5595 return StmtError();
5596 }
5597
5598 getCurFunction()->setHasBranchProtectedScope();
5599
5600 return OMPParallelSectionsDirective::Create(
5601 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5602}
5603
5604StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
5605 Stmt *AStmt, SourceLocation StartLoc,
5606 SourceLocation EndLoc) {
5607 if (!AStmt)
5608 return StmtError();
5609
5610 auto *CS = cast<CapturedStmt>(AStmt);
5611 // 1.2.2 OpenMP Language Terminology
5612 // Structured block - An executable statement with a single entry at the
5613 // top and a single exit at the bottom.
5614 // The point of exit cannot be a branch out of the structured block.
5615 // longjmp() and throw() must not violate the entry/exit criteria.
5616 CS->getCapturedDecl()->setNothrow();
5617
5618 getCurFunction()->setHasBranchProtectedScope();
5619
5620 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5621 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5622}
5623
5624StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
5625 SourceLocation EndLoc) {
5626 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5627}
5628
5629StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
5630 SourceLocation EndLoc) {
5631 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5632}
5633
5634StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
5635 SourceLocation EndLoc) {
5636 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5637}
5638
5639StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
5640 Stmt *AStmt,
5641 SourceLocation StartLoc,
5642 SourceLocation EndLoc) {
5643 if (!AStmt)
5644 return StmtError();
5645
5646 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5646, __extension__ __PRETTY_FUNCTION__))
;
5647
5648 getCurFunction()->setHasBranchProtectedScope();
5649
5650 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5651 AStmt,
5652 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
5653}
5654
5655StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
5656 SourceLocation StartLoc,
5657 SourceLocation EndLoc) {
5658 assert(Clauses.size() <= 1 && "Extra clauses in flush directive")(static_cast <bool> (Clauses.size() <= 1 && "Extra clauses in flush directive"
) ? void (0) : __assert_fail ("Clauses.size() <= 1 && \"Extra clauses in flush directive\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5658, __extension__ __PRETTY_FUNCTION__))
;
5659 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5660}
5661
5662StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
5663 Stmt *AStmt,
5664 SourceLocation StartLoc,
5665 SourceLocation EndLoc) {
5666 OMPClause *DependFound = nullptr;
5667 OMPClause *DependSourceClause = nullptr;
5668 OMPClause *DependSinkClause = nullptr;
5669 bool ErrorFound = false;
5670 OMPThreadsClause *TC = nullptr;
5671 OMPSIMDClause *SC = nullptr;
5672 for (auto *C : Clauses) {
5673 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5674 DependFound = C;
5675 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5676 if (DependSourceClause) {
5677 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5678 << getOpenMPDirectiveName(OMPD_ordered)
5679 << getOpenMPClauseName(OMPC_depend) << 2;
5680 ErrorFound = true;
5681 } else
5682 DependSourceClause = C;
5683 if (DependSinkClause) {
5684 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5685 << 0;
5686 ErrorFound = true;
5687 }
5688 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5689 if (DependSourceClause) {
5690 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5691 << 1;
5692 ErrorFound = true;
5693 }
5694 DependSinkClause = C;
5695 }
5696 } else if (C->getClauseKind() == OMPC_threads)
5697 TC = cast<OMPThreadsClause>(C);
5698 else if (C->getClauseKind() == OMPC_simd)
5699 SC = cast<OMPSIMDClause>(C);
5700 }
5701 if (!ErrorFound && !SC &&
5702 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
5703 // OpenMP [2.8.1,simd Construct, Restrictions]
5704 // An ordered construct with the simd clause is the only OpenMP construct
5705 // that can appear in the simd region.
5706 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5707 ErrorFound = true;
5708 } else if (DependFound && (TC || SC)) {
5709 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5710 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5711 ErrorFound = true;
5712 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam()) {
5713 Diag(DependFound->getLocStart(),
5714 diag::err_omp_ordered_directive_without_param);
5715 ErrorFound = true;
5716 } else if (TC || Clauses.empty()) {
5717 if (auto *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam()) {
5718 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5719 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5720 << (TC != nullptr);
5721 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5722 ErrorFound = true;
5723 }
5724 }
5725 if ((!AStmt && !DependFound) || ErrorFound)
5726 return StmtError();
5727
5728 if (AStmt) {
5729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5729, __extension__ __PRETTY_FUNCTION__))
;
5730
5731 getCurFunction()->setHasBranchProtectedScope();
5732 }
5733
5734 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5735}
5736
5737namespace {
5738/// \brief Helper class for checking expression in 'omp atomic [update]'
5739/// construct.
5740class OpenMPAtomicUpdateChecker {
5741 /// \brief Error results for atomic update expressions.
5742 enum ExprAnalysisErrorCode {
5743 /// \brief A statement is not an expression statement.
5744 NotAnExpression,
5745 /// \brief Expression is not builtin binary or unary operation.
5746 NotABinaryOrUnaryExpression,
5747 /// \brief Unary operation is not post-/pre- increment/decrement operation.
5748 NotAnUnaryIncDecExpression,
5749 /// \brief An expression is not of scalar type.
5750 NotAScalarType,
5751 /// \brief A binary operation is not an assignment operation.
5752 NotAnAssignmentOp,
5753 /// \brief RHS part of the binary operation is not a binary expression.
5754 NotABinaryExpression,
5755 /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5756 /// expression.
5757 NotABinaryOperator,
5758 /// \brief RHS binary operation does not have reference to the updated LHS
5759 /// part.
5760 NotAnUpdateExpression,
5761 /// \brief No errors is found.
5762 NoError
5763 };
5764 /// \brief Reference to Sema.
5765 Sema &SemaRef;
5766 /// \brief A location for note diagnostics (when error is found).
5767 SourceLocation NoteLoc;
5768 /// \brief 'x' lvalue part of the source atomic expression.
5769 Expr *X;
5770 /// \brief 'expr' rvalue part of the source atomic expression.
5771 Expr *E;
5772 /// \brief Helper expression of the form
5773 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5774 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5775 Expr *UpdateExpr;
5776 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5777 /// important for non-associative operations.
5778 bool IsXLHSInRHSPart;
5779 BinaryOperatorKind Op;
5780 SourceLocation OpLoc;
5781 /// \brief true if the source expression is a postfix unary operation, false
5782 /// if it is a prefix unary operation.
5783 bool IsPostfixUpdate;
5784
5785public:
5786 OpenMPAtomicUpdateChecker(Sema &SemaRef)
5787 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5788 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5789 /// \brief Check specified statement that it is suitable for 'atomic update'
5790 /// constructs and extract 'x', 'expr' and Operation from the original
5791 /// expression. If DiagId and NoteId == 0, then only check is performed
5792 /// without error notification.
5793 /// \param DiagId Diagnostic which should be emitted if error is found.
5794 /// \param NoteId Diagnostic note for the main error message.
5795 /// \return true if statement is not an update expression, false otherwise.
5796 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5797 /// \brief Return the 'x' lvalue part of the source atomic expression.
5798 Expr *getX() const { return X; }
5799 /// \brief Return the 'expr' rvalue part of the source atomic expression.
5800 Expr *getExpr() const { return E; }
5801 /// \brief Return the update expression used in calculation of the updated
5802 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5803 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5804 Expr *getUpdateExpr() const { return UpdateExpr; }
5805 /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5806 /// false otherwise.
5807 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5808
5809 /// \brief true if the source expression is a postfix unary operation, false
5810 /// if it is a prefix unary operation.
5811 bool isPostfixUpdate() const { return IsPostfixUpdate; }
5812
5813private:
5814 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5815 unsigned NoteId = 0);
5816};
5817} // namespace
5818
5819bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5820 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5821 ExprAnalysisErrorCode ErrorFound = NoError;
5822 SourceLocation ErrorLoc, NoteLoc;
5823 SourceRange ErrorRange, NoteRange;
5824 // Allowed constructs are:
5825 // x = x binop expr;
5826 // x = expr binop x;
5827 if (AtomicBinOp->getOpcode() == BO_Assign) {
5828 X = AtomicBinOp->getLHS();
5829 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5830 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5831 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5832 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5833 AtomicInnerBinOp->isBitwiseOp()) {
5834 Op = AtomicInnerBinOp->getOpcode();
5835 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5836 auto *LHS = AtomicInnerBinOp->getLHS();
5837 auto *RHS = AtomicInnerBinOp->getRHS();
5838 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5839 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5840 /*Canonical=*/true);
5841 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5842 /*Canonical=*/true);
5843 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
5844 /*Canonical=*/true);
5845 if (XId == LHSId) {
5846 E = RHS;
5847 IsXLHSInRHSPart = true;
5848 } else if (XId == RHSId) {
5849 E = LHS;
5850 IsXLHSInRHSPart = false;
5851 } else {
5852 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5853 ErrorRange = AtomicInnerBinOp->getSourceRange();
5854 NoteLoc = X->getExprLoc();
5855 NoteRange = X->getSourceRange();
5856 ErrorFound = NotAnUpdateExpression;
5857 }
5858 } else {
5859 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5860 ErrorRange = AtomicInnerBinOp->getSourceRange();
5861 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5862 NoteRange = SourceRange(NoteLoc, NoteLoc);
5863 ErrorFound = NotABinaryOperator;
5864 }
5865 } else {
5866 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
5867 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
5868 ErrorFound = NotABinaryExpression;
5869 }
5870 } else {
5871 ErrorLoc = AtomicBinOp->getExprLoc();
5872 ErrorRange = AtomicBinOp->getSourceRange();
5873 NoteLoc = AtomicBinOp->getOperatorLoc();
5874 NoteRange = SourceRange(NoteLoc, NoteLoc);
5875 ErrorFound = NotAnAssignmentOp;
5876 }
5877 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5878 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5879 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5880 return true;
5881 } else if (SemaRef.CurContext->isDependentContext())
5882 E = X = UpdateExpr = nullptr;
5883 return ErrorFound != NoError;
5884}
5885
5886bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
5887 unsigned NoteId) {
5888 ExprAnalysisErrorCode ErrorFound = NoError;
5889 SourceLocation ErrorLoc, NoteLoc;
5890 SourceRange ErrorRange, NoteRange;
5891 // Allowed constructs are:
5892 // x++;
5893 // x--;
5894 // ++x;
5895 // --x;
5896 // x binop= expr;
5897 // x = x binop expr;
5898 // x = expr binop x;
5899 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
5900 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5901 if (AtomicBody->getType()->isScalarType() ||
5902 AtomicBody->isInstantiationDependent()) {
5903 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5904 AtomicBody->IgnoreParenImpCasts())) {
5905 // Check for Compound Assignment Operation
5906 Op = BinaryOperator::getOpForCompoundAssignment(
5907 AtomicCompAssignOp->getOpcode());
5908 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5909 E = AtomicCompAssignOp->getRHS();
5910 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5911 IsXLHSInRHSPart = true;
5912 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5913 AtomicBody->IgnoreParenImpCasts())) {
5914 // Check for Binary Operation
5915 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5916 return true;
5917 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5918 AtomicBody->IgnoreParenImpCasts())) {
5919 // Check for Unary Operation
5920 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5921 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5922 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5923 OpLoc = AtomicUnaryOp->getOperatorLoc();
5924 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5925 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
5926 IsXLHSInRHSPart = true;
5927 } else {
5928 ErrorFound = NotAnUnaryIncDecExpression;
5929 ErrorLoc = AtomicUnaryOp->getExprLoc();
5930 ErrorRange = AtomicUnaryOp->getSourceRange();
5931 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5932 NoteRange = SourceRange(NoteLoc, NoteLoc);
5933 }
5934 } else if (!AtomicBody->isInstantiationDependent()) {
5935 ErrorFound = NotABinaryOrUnaryExpression;
5936 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5937 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5938 }
5939 } else {
5940 ErrorFound = NotAScalarType;
5941 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5942 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5943 }
5944 } else {
5945 ErrorFound = NotAnExpression;
5946 NoteLoc = ErrorLoc = S->getLocStart();
5947 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5948 }
5949 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5950 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5951 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5952 return true;
5953 } else if (SemaRef.CurContext->isDependentContext())
5954 E = X = UpdateExpr = nullptr;
5955 if (ErrorFound == NoError && E && X) {
5956 // Build an update expression of form 'OpaqueValueExpr(x) binop
5957 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
5958 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
5959 auto *OVEX = new (SemaRef.getASTContext())
5960 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
5961 auto *OVEExpr = new (SemaRef.getASTContext())
5962 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
5963 auto Update =
5964 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
5965 IsXLHSInRHSPart ? OVEExpr : OVEX);
5966 if (Update.isInvalid())
5967 return true;
5968 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
5969 Sema::AA_Casting);
5970 if (Update.isInvalid())
5971 return true;
5972 UpdateExpr = Update.get();
5973 }
5974 return ErrorFound != NoError;
5975}
5976
5977StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
5978 Stmt *AStmt,
5979 SourceLocation StartLoc,
5980 SourceLocation EndLoc) {
5981 if (!AStmt)
5982 return StmtError();
5983
5984 auto *CS = cast<CapturedStmt>(AStmt);
5985 // 1.2.2 OpenMP Language Terminology
5986 // Structured block - An executable statement with a single entry at the
5987 // top and a single exit at the bottom.
5988 // The point of exit cannot be a branch out of the structured block.
5989 // longjmp() and throw() must not violate the entry/exit criteria.
5990 OpenMPClauseKind AtomicKind = OMPC_unknown;
5991 SourceLocation AtomicKindLoc;
5992 for (auto *C : Clauses) {
5993 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5994 C->getClauseKind() == OMPC_update ||
5995 C->getClauseKind() == OMPC_capture) {
5996 if (AtomicKind != OMPC_unknown) {
5997 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5998 << SourceRange(C->getLocStart(), C->getLocEnd());
5999 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6000 << getOpenMPClauseName(AtomicKind);
6001 } else {
6002 AtomicKind = C->getClauseKind();
6003 AtomicKindLoc = C->getLocStart();
6004 }
6005 }
6006 }
6007
6008 auto Body = CS->getCapturedStmt();
6009 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6010 Body = EWC->getSubExpr();
6011
6012 Expr *X = nullptr;
6013 Expr *V = nullptr;
6014 Expr *E = nullptr;
6015 Expr *UE = nullptr;
6016 bool IsXLHSInRHSPart = false;
6017 bool IsPostfixUpdate = false;
6018 // OpenMP [2.12.6, atomic Construct]
6019 // In the next expressions:
6020 // * x and v (as applicable) are both l-value expressions with scalar type.
6021 // * During the execution of an atomic region, multiple syntactic
6022 // occurrences of x must designate the same storage location.
6023 // * Neither of v and expr (as applicable) may access the storage location
6024 // designated by x.
6025 // * Neither of x and expr (as applicable) may access the storage location
6026 // designated by v.
6027 // * expr is an expression with scalar type.
6028 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6029 // * binop, binop=, ++, and -- are not overloaded operators.
6030 // * The expression x binop expr must be numerically equivalent to x binop
6031 // (expr). This requirement is satisfied if the operators in expr have
6032 // precedence greater than binop, or by using parentheses around expr or
6033 // subexpressions of expr.
6034 // * The expression expr binop x must be numerically equivalent to (expr)
6035 // binop x. This requirement is satisfied if the operators in expr have
6036 // precedence equal to or greater than binop, or by using parentheses around
6037 // expr or subexpressions of expr.
6038 // * For forms that allow multiple occurrences of x, the number of times
6039 // that x is evaluated is unspecified.
6040 if (AtomicKind == OMPC_read) {
6041 enum {
6042 NotAnExpression,
6043 NotAnAssignmentOp,
6044 NotAScalarType,
6045 NotAnLValue,
6046 NoError
6047 } ErrorFound = NoError;
6048 SourceLocation ErrorLoc, NoteLoc;
6049 SourceRange ErrorRange, NoteRange;
6050 // If clause is read:
6051 // v = x;
6052 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6053 auto *AtomicBinOp =
6054 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6055 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6056 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6057 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6058 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6059 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6060 if (!X->isLValue() || !V->isLValue()) {
6061 auto NotLValueExpr = X->isLValue() ? V : X;
6062 ErrorFound = NotAnLValue;
6063 ErrorLoc = AtomicBinOp->getExprLoc();
6064 ErrorRange = AtomicBinOp->getSourceRange();
6065 NoteLoc = NotLValueExpr->getExprLoc();
6066 NoteRange = NotLValueExpr->getSourceRange();
6067 }
6068 } else if (!X->isInstantiationDependent() ||
6069 !V->isInstantiationDependent()) {
6070 auto NotScalarExpr =
6071 (X->isInstantiationDependent() || X->getType()->isScalarType())
6072 ? V
6073 : X;
6074 ErrorFound = NotAScalarType;
6075 ErrorLoc = AtomicBinOp->getExprLoc();
6076 ErrorRange = AtomicBinOp->getSourceRange();
6077 NoteLoc = NotScalarExpr->getExprLoc();
6078 NoteRange = NotScalarExpr->getSourceRange();
6079 }
6080 } else if (!AtomicBody->isInstantiationDependent()) {
6081 ErrorFound = NotAnAssignmentOp;
6082 ErrorLoc = AtomicBody->getExprLoc();
6083 ErrorRange = AtomicBody->getSourceRange();
6084 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6085 : AtomicBody->getExprLoc();
6086 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6087 : AtomicBody->getSourceRange();
6088 }
6089 } else {
6090 ErrorFound = NotAnExpression;
6091 NoteLoc = ErrorLoc = Body->getLocStart();
6092 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6093 }
6094 if (ErrorFound != NoError) {
6095 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6096 << ErrorRange;
6097 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6098 << NoteRange;
6099 return StmtError();
6100 } else if (CurContext->isDependentContext())
6101 V = X = nullptr;
6102 } else if (AtomicKind == OMPC_write) {
6103 enum {
6104 NotAnExpression,
6105 NotAnAssignmentOp,
6106 NotAScalarType,
6107 NotAnLValue,
6108 NoError
6109 } ErrorFound = NoError;
6110 SourceLocation ErrorLoc, NoteLoc;
6111 SourceRange ErrorRange, NoteRange;
6112 // If clause is write:
6113 // x = expr;
6114 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6115 auto *AtomicBinOp =
6116 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6117 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6118 X = AtomicBinOp->getLHS();
6119 E = AtomicBinOp->getRHS();
6120 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6121 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6122 if (!X->isLValue()) {
6123 ErrorFound = NotAnLValue;
6124 ErrorLoc = AtomicBinOp->getExprLoc();
6125 ErrorRange = AtomicBinOp->getSourceRange();
6126 NoteLoc = X->getExprLoc();
6127 NoteRange = X->getSourceRange();
6128 }
6129 } else if (!X->isInstantiationDependent() ||
6130 !E->isInstantiationDependent()) {
6131 auto NotScalarExpr =
6132 (X->isInstantiationDependent() || X->getType()->isScalarType())
6133 ? E
6134 : X;
6135 ErrorFound = NotAScalarType;
6136 ErrorLoc = AtomicBinOp->getExprLoc();
6137 ErrorRange = AtomicBinOp->getSourceRange();
6138 NoteLoc = NotScalarExpr->getExprLoc();
6139 NoteRange = NotScalarExpr->getSourceRange();
6140 }
6141 } else if (!AtomicBody->isInstantiationDependent()) {
6142 ErrorFound = NotAnAssignmentOp;
6143 ErrorLoc = AtomicBody->getExprLoc();
6144 ErrorRange = AtomicBody->getSourceRange();
6145 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6146 : AtomicBody->getExprLoc();
6147 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6148 : AtomicBody->getSourceRange();
6149 }
6150 } else {
6151 ErrorFound = NotAnExpression;
6152 NoteLoc = ErrorLoc = Body->getLocStart();
6153 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6154 }
6155 if (ErrorFound != NoError) {
6156 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6157 << ErrorRange;
6158 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6159 << NoteRange;
6160 return StmtError();
6161 } else if (CurContext->isDependentContext())
6162 E = X = nullptr;
6163 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6164 // If clause is update:
6165 // x++;
6166 // x--;
6167 // ++x;
6168 // --x;
6169 // x binop= expr;
6170 // x = x binop expr;
6171 // x = expr binop x;
6172 OpenMPAtomicUpdateChecker Checker(*this);
6173 if (Checker.checkStatement(
6174 Body, (AtomicKind == OMPC_update)
6175 ? diag::err_omp_atomic_update_not_expression_statement
6176 : diag::err_omp_atomic_not_expression_statement,
6177 diag::note_omp_atomic_update))
6178 return StmtError();
6179 if (!CurContext->isDependentContext()) {
6180 E = Checker.getExpr();
6181 X = Checker.getX();
6182 UE = Checker.getUpdateExpr();
6183 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6184 }
6185 } else if (AtomicKind == OMPC_capture) {
6186 enum {
6187 NotAnAssignmentOp,
6188 NotACompoundStatement,
6189 NotTwoSubstatements,
6190 NotASpecificExpression,
6191 NoError
6192 } ErrorFound = NoError;
6193 SourceLocation ErrorLoc, NoteLoc;
6194 SourceRange ErrorRange, NoteRange;
6195 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6196 // If clause is a capture:
6197 // v = x++;
6198 // v = x--;
6199 // v = ++x;
6200 // v = --x;
6201 // v = x binop= expr;
6202 // v = x = x binop expr;
6203 // v = x = expr binop x;
6204 auto *AtomicBinOp =
6205 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6206 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6207 V = AtomicBinOp->getLHS();
6208 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6209 OpenMPAtomicUpdateChecker Checker(*this);
6210 if (Checker.checkStatement(
6211 Body, diag::err_omp_atomic_capture_not_expression_statement,
6212 diag::note_omp_atomic_update))
6213 return StmtError();
6214 E = Checker.getExpr();
6215 X = Checker.getX();
6216 UE = Checker.getUpdateExpr();
6217 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6218 IsPostfixUpdate = Checker.isPostfixUpdate();
6219 } else if (!AtomicBody->isInstantiationDependent()) {
6220 ErrorLoc = AtomicBody->getExprLoc();
6221 ErrorRange = AtomicBody->getSourceRange();
6222 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6223 : AtomicBody->getExprLoc();
6224 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6225 : AtomicBody->getSourceRange();
6226 ErrorFound = NotAnAssignmentOp;
6227 }
6228 if (ErrorFound != NoError) {
6229 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6230 << ErrorRange;
6231 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6232 return StmtError();
6233 } else if (CurContext->isDependentContext()) {
6234 UE = V = E = X = nullptr;
6235 }
6236 } else {
6237 // If clause is a capture:
6238 // { v = x; x = expr; }
6239 // { v = x; x++; }
6240 // { v = x; x--; }
6241 // { v = x; ++x; }
6242 // { v = x; --x; }
6243 // { v = x; x binop= expr; }
6244 // { v = x; x = x binop expr; }
6245 // { v = x; x = expr binop x; }
6246 // { x++; v = x; }
6247 // { x--; v = x; }
6248 // { ++x; v = x; }
6249 // { --x; v = x; }
6250 // { x binop= expr; v = x; }
6251 // { x = x binop expr; v = x; }
6252 // { x = expr binop x; v = x; }
6253 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6254 // Check that this is { expr1; expr2; }
6255 if (CS->size() == 2) {
6256 auto *First = CS->body_front();
6257 auto *Second = CS->body_back();
6258 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6259 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6260 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6261 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6262 // Need to find what subexpression is 'v' and what is 'x'.
6263 OpenMPAtomicUpdateChecker Checker(*this);
6264 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6265 BinaryOperator *BinOp = nullptr;
6266 if (IsUpdateExprFound) {
6267 BinOp = dyn_cast<BinaryOperator>(First);
6268 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6269 }
6270 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6271 // { v = x; x++; }
6272 // { v = x; x--; }
6273 // { v = x; ++x; }
6274 // { v = x; --x; }
6275 // { v = x; x binop= expr; }
6276 // { v = x; x = x binop expr; }
6277 // { v = x; x = expr binop x; }
6278 // Check that the first expression has form v = x.
6279 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6280 llvm::FoldingSetNodeID XId, PossibleXId;
6281 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6282 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6283 IsUpdateExprFound = XId == PossibleXId;
6284 if (IsUpdateExprFound) {
6285 V = BinOp->getLHS();
6286 X = Checker.getX();
6287 E = Checker.getExpr();
6288 UE = Checker.getUpdateExpr();
6289 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6290 IsPostfixUpdate = true;
6291 }
6292 }
6293 if (!IsUpdateExprFound) {
6294 IsUpdateExprFound = !Checker.checkStatement(First);
6295 BinOp = nullptr;
6296 if (IsUpdateExprFound) {
6297 BinOp = dyn_cast<BinaryOperator>(Second);
6298 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6299 }
6300 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6301 // { x++; v = x; }
6302 // { x--; v = x; }
6303 // { ++x; v = x; }
6304 // { --x; v = x; }
6305 // { x binop= expr; v = x; }
6306 // { x = x binop expr; v = x; }
6307 // { x = expr binop x; v = x; }
6308 // Check that the second expression has form v = x.
6309 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6310 llvm::FoldingSetNodeID XId, PossibleXId;
6311 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6312 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6313 IsUpdateExprFound = XId == PossibleXId;
6314 if (IsUpdateExprFound) {
6315 V = BinOp->getLHS();
6316 X = Checker.getX();
6317 E = Checker.getExpr();
6318 UE = Checker.getUpdateExpr();
6319 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6320 IsPostfixUpdate = false;
6321 }
6322 }
6323 }
6324 if (!IsUpdateExprFound) {
6325 // { v = x; x = expr; }
6326 auto *FirstExpr = dyn_cast<Expr>(First);
6327 auto *SecondExpr = dyn_cast<Expr>(Second);
6328 if (!FirstExpr || !SecondExpr ||
6329 !(FirstExpr->isInstantiationDependent() ||
6330 SecondExpr->isInstantiationDependent())) {
6331 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6332 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6333 ErrorFound = NotAnAssignmentOp;
6334 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6335 : First->getLocStart();
6336 NoteRange = ErrorRange = FirstBinOp
6337 ? FirstBinOp->getSourceRange()
6338 : SourceRange(ErrorLoc, ErrorLoc);
6339 } else {
6340 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6341 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6342 ErrorFound = NotAnAssignmentOp;
6343 NoteLoc = ErrorLoc = SecondBinOp
6344 ? SecondBinOp->getOperatorLoc()
6345 : Second->getLocStart();
6346 NoteRange = ErrorRange =
6347 SecondBinOp ? SecondBinOp->getSourceRange()
6348 : SourceRange(ErrorLoc, ErrorLoc);
6349 } else {
6350 auto *PossibleXRHSInFirst =
6351 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6352 auto *PossibleXLHSInSecond =
6353 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6354 llvm::FoldingSetNodeID X1Id, X2Id;
6355 PossibleXRHSInFirst->Profile(X1Id, Context,
6356 /*Canonical=*/true);
6357 PossibleXLHSInSecond->Profile(X2Id, Context,
6358 /*Canonical=*/true);
6359 IsUpdateExprFound = X1Id == X2Id;
6360 if (IsUpdateExprFound) {
6361 V = FirstBinOp->getLHS();
6362 X = SecondBinOp->getLHS();
6363 E = SecondBinOp->getRHS();
6364 UE = nullptr;
6365 IsXLHSInRHSPart = false;
6366 IsPostfixUpdate = true;
6367 } else {
6368 ErrorFound = NotASpecificExpression;
6369 ErrorLoc = FirstBinOp->getExprLoc();
6370 ErrorRange = FirstBinOp->getSourceRange();
6371 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6372 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6373 }
6374 }
6375 }
6376 }
6377 }
6378 } else {
6379 NoteLoc = ErrorLoc = Body->getLocStart();
6380 NoteRange = ErrorRange =
6381 SourceRange(Body->getLocStart(), Body->getLocStart());
6382 ErrorFound = NotTwoSubstatements;
6383 }
6384 } else {
6385 NoteLoc = ErrorLoc = Body->getLocStart();
6386 NoteRange = ErrorRange =
6387 SourceRange(Body->getLocStart(), Body->getLocStart());
6388 ErrorFound = NotACompoundStatement;
6389 }
6390 if (ErrorFound != NoError) {
6391 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6392 << ErrorRange;
6393 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6394 return StmtError();
6395 } else if (CurContext->isDependentContext()) {
6396 UE = V = E = X = nullptr;
6397 }
6398 }
6399 }
6400
6401 getCurFunction()->setHasBranchProtectedScope();
6402
6403 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6404 X, V, E, UE, IsXLHSInRHSPart,
6405 IsPostfixUpdate);
6406}
6407
6408StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6409 Stmt *AStmt,
6410 SourceLocation StartLoc,
6411 SourceLocation EndLoc) {
6412 if (!AStmt)
6413 return StmtError();
6414
6415 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6416 // 1.2.2 OpenMP Language Terminology
6417 // Structured block - An executable statement with a single entry at the
6418 // top and a single exit at the bottom.
6419 // The point of exit cannot be a branch out of the structured block.
6420 // longjmp() and throw() must not violate the entry/exit criteria.
6421 CS->getCapturedDecl()->setNothrow();
6422 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6423 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6424 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6425 // 1.2.2 OpenMP Language Terminology
6426 // Structured block - An executable statement with a single entry at the
6427 // top and a single exit at the bottom.
6428 // The point of exit cannot be a branch out of the structured block.
6429 // longjmp() and throw() must not violate the entry/exit criteria.
6430 CS->getCapturedDecl()->setNothrow();
6431 }
6432
6433 // OpenMP [2.16, Nesting of Regions]
6434 // If specified, a teams construct must be contained within a target
6435 // construct. That target construct must contain no statements or directives
6436 // outside of the teams construct.
6437 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
6438 Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
6439 bool OMPTeamsFound = true;
6440 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6441 auto I = CS->body_begin();
6442 while (I != CS->body_end()) {
6443 auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6444 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6445 OMPTeamsFound = false;
6446 break;
6447 }
6448 ++I;
6449 }
6450 assert(I != CS->body_end() && "Not found statement")(static_cast <bool> (I != CS->body_end() && "Not found statement"
) ? void (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6450, __extension__ __PRETTY_FUNCTION__))
;
6451 S = *I;
6452 } else {
6453 auto *OED = dyn_cast<OMPExecutableDirective>(S);
6454 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6455 }
6456 if (!OMPTeamsFound) {
6457 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6458 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
6459 diag::note_omp_nested_teams_construct_here);
6460 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6461 << isa<OMPExecutableDirective>(S);
6462 return StmtError();
6463 }
6464 }
6465
6466 getCurFunction()->setHasBranchProtectedScope();
6467
6468 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6469}
6470
6471StmtResult
6472Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
6473 Stmt *AStmt, SourceLocation StartLoc,
6474 SourceLocation EndLoc) {
6475 if (!AStmt)
6476 return StmtError();
6477
6478 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6479 // 1.2.2 OpenMP Language Terminology
6480 // Structured block - An executable statement with a single entry at the
6481 // top and a single exit at the bottom.
6482 // The point of exit cannot be a branch out of the structured block.
6483 // longjmp() and throw() must not violate the entry/exit criteria.
6484 CS->getCapturedDecl()->setNothrow();
6485 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
6486 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6487 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6488 // 1.2.2 OpenMP Language Terminology
6489 // Structured block - An executable statement with a single entry at the
6490 // top and a single exit at the bottom.
6491 // The point of exit cannot be a branch out of the structured block.
6492 // longjmp() and throw() must not violate the entry/exit criteria.
6493 CS->getCapturedDecl()->setNothrow();
6494 }
6495
6496 getCurFunction()->setHasBranchProtectedScope();
6497
6498 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6499 AStmt);
6500}
6501
6502StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
6503 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6504 SourceLocation EndLoc,
6505 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6506 if (!AStmt)
6507 return StmtError();
6508
6509 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6510 // 1.2.2 OpenMP Language Terminology
6511 // Structured block - An executable statement with a single entry at the
6512 // top and a single exit at the bottom.
6513 // The point of exit cannot be a branch out of the structured block.
6514 // longjmp() and throw() must not violate the entry/exit criteria.
6515 CS->getCapturedDecl()->setNothrow();
6516 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6517 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6518 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6519 // 1.2.2 OpenMP Language Terminology
6520 // Structured block - An executable statement with a single entry at the
6521 // top and a single exit at the bottom.
6522 // The point of exit cannot be a branch out of the structured block.
6523 // longjmp() and throw() must not violate the entry/exit criteria.
6524 CS->getCapturedDecl()->setNothrow();
6525 }
6526
6527 OMPLoopDirective::HelperExprs B;
6528 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6529 // define the nested loops number.
6530 unsigned NestedLoopCount =
6531 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6532 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6533 VarsWithImplicitDSA, B);
6534 if (NestedLoopCount == 0)
6535 return StmtError();
6536
6537 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6538, __extension__ __PRETTY_FUNCTION__))
6538 "omp target parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6538, __extension__ __PRETTY_FUNCTION__))
;
6539
6540 if (!CurContext->isDependentContext()) {
6541 // Finalize the clauses that need pre-built expressions for CodeGen.
6542 for (auto C : Clauses) {
6543 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6544 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6545 B.NumIterations, *this, CurScope,
6546 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6547 return StmtError();
6548 }
6549 }
6550
6551 getCurFunction()->setHasBranchProtectedScope();
6552 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6553 NestedLoopCount, Clauses, AStmt,
6554 B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6555}
6556
6557/// Check for existence of a map clause in the list of clauses.
6558static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6559 const OpenMPClauseKind K) {
6560 return llvm::any_of(
6561 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6562}
6563
6564template <typename... Params>
6565static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
6566 const Params... ClauseTypes) {
6567 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6568}
6569
6570StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
6571 Stmt *AStmt,
6572 SourceLocation StartLoc,
6573 SourceLocation EndLoc) {
6574 if (!AStmt)
6575 return StmtError();
6576
6577 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6577, __extension__ __PRETTY_FUNCTION__))
;
6578
6579 // OpenMP [2.10.1, Restrictions, p. 97]
6580 // At least one map clause must appear on the directive.
6581 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6582 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6583 << "'map' or 'use_device_ptr'"
6584 << getOpenMPDirectiveName(OMPD_target_data);
6585 return StmtError();
6586 }
6587
6588 getCurFunction()->setHasBranchProtectedScope();
6589
6590 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6591 AStmt);
6592}
6593
6594StmtResult
6595Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
6596 SourceLocation StartLoc,
6597 SourceLocation EndLoc, Stmt *AStmt) {
6598 if (!AStmt)
6599 return StmtError();
6600
6601 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6602 // 1.2.2 OpenMP Language Terminology
6603 // Structured block - An executable statement with a single entry at the
6604 // top and a single exit at the bottom.
6605 // The point of exit cannot be a branch out of the structured block.
6606 // longjmp() and throw() must not violate the entry/exit criteria.
6607 CS->getCapturedDecl()->setNothrow();
6608 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6609 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6610 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6611 // 1.2.2 OpenMP Language Terminology
6612 // Structured block - An executable statement with a single entry at the
6613 // top and a single exit at the bottom.
6614 // The point of exit cannot be a branch out of the structured block.
6615 // longjmp() and throw() must not violate the entry/exit criteria.
6616 CS->getCapturedDecl()->setNothrow();
6617 }
6618
6619 // OpenMP [2.10.2, Restrictions, p. 99]
6620 // At least one map clause must appear on the directive.
6621 if (!hasClauses(Clauses, OMPC_map)) {
6622 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6623 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6624 return StmtError();
6625 }
6626
6627 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6628 AStmt);
6629}
6630
6631StmtResult
6632Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
6633 SourceLocation StartLoc,
6634 SourceLocation EndLoc, Stmt *AStmt) {
6635 if (!AStmt)
6636 return StmtError();
6637
6638 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6639 // 1.2.2 OpenMP Language Terminology
6640 // Structured block - An executable statement with a single entry at the
6641 // top and a single exit at the bottom.
6642 // The point of exit cannot be a branch out of the structured block.
6643 // longjmp() and throw() must not violate the entry/exit criteria.
6644 CS->getCapturedDecl()->setNothrow();
6645 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6646 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6647 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6648 // 1.2.2 OpenMP Language Terminology
6649 // Structured block - An executable statement with a single entry at the
6650 // top and a single exit at the bottom.
6651 // The point of exit cannot be a branch out of the structured block.
6652 // longjmp() and throw() must not violate the entry/exit criteria.
6653 CS->getCapturedDecl()->setNothrow();
6654 }
6655
6656 // OpenMP [2.10.3, Restrictions, p. 102]
6657 // At least one map clause must appear on the directive.
6658 if (!hasClauses(Clauses, OMPC_map)) {
6659 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6660 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6661 return StmtError();
6662 }
6663
6664 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6665 AStmt);
6666}
6667
6668StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
6669 SourceLocation StartLoc,
6670 SourceLocation EndLoc,
6671 Stmt *AStmt) {
6672 if (!AStmt)
6673 return StmtError();
6674
6675 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6676 // 1.2.2 OpenMP Language Terminology
6677 // Structured block - An executable statement with a single entry at the
6678 // top and a single exit at the bottom.
6679 // The point of exit cannot be a branch out of the structured block.
6680 // longjmp() and throw() must not violate the entry/exit criteria.
6681 CS->getCapturedDecl()->setNothrow();
6682 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6683 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6684 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6685 // 1.2.2 OpenMP Language Terminology
6686 // Structured block - An executable statement with a single entry at the
6687 // top and a single exit at the bottom.
6688 // The point of exit cannot be a branch out of the structured block.
6689 // longjmp() and throw() must not violate the entry/exit criteria.
6690 CS->getCapturedDecl()->setNothrow();
6691 }
6692
6693 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6694 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6695 return StmtError();
6696 }
6697 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6698 AStmt);
6699}
6700
6701StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
6702 Stmt *AStmt, SourceLocation StartLoc,
6703 SourceLocation EndLoc) {
6704 if (!AStmt)
6705 return StmtError();
6706
6707 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6708 // 1.2.2 OpenMP Language Terminology
6709 // Structured block - An executable statement with a single entry at the
6710 // top and a single exit at the bottom.
6711 // The point of exit cannot be a branch out of the structured block.
6712 // longjmp() and throw() must not violate the entry/exit criteria.
6713 CS->getCapturedDecl()->setNothrow();
6714
6715 getCurFunction()->setHasBranchProtectedScope();
6716
6717 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
6718
6719 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6720}
6721
6722StmtResult
6723Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
6724 SourceLocation EndLoc,
6725 OpenMPDirectiveKind CancelRegion) {
6726 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
6727 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6728 return StmtError();
6729 }
6730 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
6731 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6732 return StmtError();
6733 }
6734 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6735 CancelRegion);
6736}
6737
6738StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
6739 SourceLocation StartLoc,
6740 SourceLocation EndLoc,
6741 OpenMPDirectiveKind CancelRegion) {
6742 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
6743 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6744 return StmtError();
6745 }
6746 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
6747 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6748 return StmtError();
6749 }
6750 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
6751 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6752 CancelRegion);
6753}
6754
6755static bool checkGrainsizeNumTasksClauses(Sema &S,
6756 ArrayRef<OMPClause *> Clauses) {
6757 OMPClause *PrevClause = nullptr;
6758 bool ErrorFound = false;
6759 for (auto *C : Clauses) {
6760 if (C->getClauseKind() == OMPC_grainsize ||
6761 C->getClauseKind() == OMPC_num_tasks) {
6762 if (!PrevClause)
6763 PrevClause = C;
6764 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6765 S.Diag(C->getLocStart(),
6766 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6767 << getOpenMPClauseName(C->getClauseKind())
6768 << getOpenMPClauseName(PrevClause->getClauseKind());
6769 S.Diag(PrevClause->getLocStart(),
6770 diag::note_omp_previous_grainsize_num_tasks)
6771 << getOpenMPClauseName(PrevClause->getClauseKind());
6772 ErrorFound = true;
6773 }
6774 }
6775 }
6776 return ErrorFound;
6777}
6778
6779static bool checkReductionClauseWithNogroup(Sema &S,
6780 ArrayRef<OMPClause *> Clauses) {
6781 OMPClause *ReductionClause = nullptr;
6782 OMPClause *NogroupClause = nullptr;
6783 for (auto *C : Clauses) {
6784 if (C->getClauseKind() == OMPC_reduction) {
6785 ReductionClause = C;
6786 if (NogroupClause)
6787 break;
6788 continue;
6789 }
6790 if (C->getClauseKind() == OMPC_nogroup) {
6791 NogroupClause = C;
6792 if (ReductionClause)
6793 break;
6794 continue;
6795 }
6796 }
6797 if (ReductionClause && NogroupClause) {
6798 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
6799 << SourceRange(NogroupClause->getLocStart(),
6800 NogroupClause->getLocEnd());
6801 return true;
6802 }
6803 return false;
6804}
6805
6806StmtResult Sema::ActOnOpenMPTaskLoopDirective(
6807 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6808 SourceLocation EndLoc,
6809 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6810 if (!AStmt)
6811 return StmtError();
6812
6813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6813, __extension__ __PRETTY_FUNCTION__))
;
6814 OMPLoopDirective::HelperExprs B;
6815 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6816 // define the nested loops number.
6817 unsigned NestedLoopCount =
6818 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6819 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6820 VarsWithImplicitDSA, B);
6821 if (NestedLoopCount == 0)
6822 return StmtError();
6823
6824 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6825, __extension__ __PRETTY_FUNCTION__))
6825 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6825, __extension__ __PRETTY_FUNCTION__))
;
6826
6827 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6828 // The grainsize clause and num_tasks clause are mutually exclusive and may
6829 // not appear on the same taskloop directive.
6830 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6831 return StmtError();
6832 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6833 // If a reduction clause is present on the taskloop directive, the nogroup
6834 // clause must not be specified.
6835 if (checkReductionClauseWithNogroup(*this, Clauses))
6836 return StmtError();
6837
6838 getCurFunction()->setHasBranchProtectedScope();
6839 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6840 NestedLoopCount, Clauses, AStmt, B);
6841}
6842
6843StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
6844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6845 SourceLocation EndLoc,
6846 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6847 if (!AStmt)
6848 return StmtError();
6849
6850 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6850, __extension__ __PRETTY_FUNCTION__))
;
6851 OMPLoopDirective::HelperExprs B;
6852 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6853 // define the nested loops number.
6854 unsigned NestedLoopCount =
6855 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
6856 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6857 VarsWithImplicitDSA, B);
6858 if (NestedLoopCount == 0)
6859 return StmtError();
6860
6861 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6862, __extension__ __PRETTY_FUNCTION__))
6862 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6862, __extension__ __PRETTY_FUNCTION__))
;
6863
6864 if (!CurContext->isDependentContext()) {
6865 // Finalize the clauses that need pre-built expressions for CodeGen.
6866 for (auto C : Clauses) {
6867 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6868 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6869 B.NumIterations, *this, CurScope,
6870 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6871 return StmtError();
6872 }
6873 }
6874
6875 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6876 // The grainsize clause and num_tasks clause are mutually exclusive and may
6877 // not appear on the same taskloop directive.
6878 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6879 return StmtError();
6880 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6881 // If a reduction clause is present on the taskloop directive, the nogroup
6882 // clause must not be specified.
6883 if (checkReductionClauseWithNogroup(*this, Clauses))
6884 return StmtError();
6885 if (checkSimdlenSafelenSpecified(*this, Clauses))
6886 return StmtError();
6887
6888 getCurFunction()->setHasBranchProtectedScope();
6889 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
6890 NestedLoopCount, Clauses, AStmt, B);
6891}
6892
6893StmtResult Sema::ActOnOpenMPDistributeDirective(
6894 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6895 SourceLocation EndLoc,
6896 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6897 if (!AStmt)
6898 return StmtError();
6899
6900 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")(static_cast <bool> (isa<CapturedStmt>(AStmt) &&
"Captured statement expected") ? void (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6900, __extension__ __PRETTY_FUNCTION__))
;
6901 OMPLoopDirective::HelperExprs B;
6902 // In presence of clause 'collapse' with number of loops, it will
6903 // define the nested loops number.
6904 unsigned NestedLoopCount =
6905 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
6906 nullptr /*ordered not a clause on distribute*/, AStmt,
6907 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
6908 if (NestedLoopCount == 0)
6909 return StmtError();
6910
6911 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6912, __extension__ __PRETTY_FUNCTION__))
6912 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6912, __extension__ __PRETTY_FUNCTION__))
;
6913
6914 getCurFunction()->setHasBranchProtectedScope();
6915 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
6916 NestedLoopCount, Clauses, AStmt, B);
6917}
6918
6919StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
6920 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6921 SourceLocation EndLoc,
6922 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6923 if (!AStmt)
6924 return StmtError();
6925
6926 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6927 // 1.2.2 OpenMP Language Terminology
6928 // Structured block - An executable statement with a single entry at the
6929 // top and a single exit at the bottom.
6930 // The point of exit cannot be a branch out of the structured block.
6931 // longjmp() and throw() must not violate the entry/exit criteria.
6932 CS->getCapturedDecl()->setNothrow();
6933 for (int ThisCaptureLevel =
6934 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6935 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6936 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6937 // 1.2.2 OpenMP Language Terminology
6938 // Structured block - An executable statement with a single entry at the
6939 // top and a single exit at the bottom.
6940 // The point of exit cannot be a branch out of the structured block.
6941 // longjmp() and throw() must not violate the entry/exit criteria.
6942 CS->getCapturedDecl()->setNothrow();
6943 }
6944
6945 OMPLoopDirective::HelperExprs B;
6946 // In presence of clause 'collapse' with number of loops, it will
6947 // define the nested loops number.
6948 unsigned NestedLoopCount = CheckOpenMPLoop(
6949 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
6950 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6951 VarsWithImplicitDSA, B);
6952 if (NestedLoopCount == 0)
6953 return StmtError();
6954
6955 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6956, __extension__ __PRETTY_FUNCTION__))
6956 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6956, __extension__ __PRETTY_FUNCTION__))
;
6957
6958 getCurFunction()->setHasBranchProtectedScope();
6959 return OMPDistributeParallelForDirective::Create(
6960 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6961 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6962}
6963
6964StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
6965 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6966 SourceLocation EndLoc,
6967 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6968 if (!AStmt)
6969 return StmtError();
6970
6971 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6972 // 1.2.2 OpenMP Language Terminology
6973 // Structured block - An executable statement with a single entry at the
6974 // top and a single exit at the bottom.
6975 // The point of exit cannot be a branch out of the structured block.
6976 // longjmp() and throw() must not violate the entry/exit criteria.
6977 CS->getCapturedDecl()->setNothrow();
6978 for (int ThisCaptureLevel =
6979 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6980 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6981 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6982 // 1.2.2 OpenMP Language Terminology
6983 // Structured block - An executable statement with a single entry at the
6984 // top and a single exit at the bottom.
6985 // The point of exit cannot be a branch out of the structured block.
6986 // longjmp() and throw() must not violate the entry/exit criteria.
6987 CS->getCapturedDecl()->setNothrow();
6988 }
6989
6990 OMPLoopDirective::HelperExprs B;
6991 // In presence of clause 'collapse' with number of loops, it will
6992 // define the nested loops number.
6993 unsigned NestedLoopCount = CheckOpenMPLoop(
6994 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
6995 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6996 VarsWithImplicitDSA, B);
6997 if (NestedLoopCount == 0)
6998 return StmtError();
6999
7000 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7001, __extension__ __PRETTY_FUNCTION__))
7001 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7001, __extension__ __PRETTY_FUNCTION__))
;
7002
7003 if (!CurContext->isDependentContext()) {
7004 // Finalize the clauses that need pre-built expressions for CodeGen.
7005 for (auto C : Clauses) {
7006 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7007 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7008 B.NumIterations, *this, CurScope,
7009 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7010 return StmtError();
7011 }
7012 }
7013
7014 if (checkSimdlenSafelenSpecified(*this, Clauses))
7015 return StmtError();
7016
7017 getCurFunction()->setHasBranchProtectedScope();
7018 return OMPDistributeParallelForSimdDirective::Create(
7019 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7020}
7021
7022StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
7023 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7024 SourceLocation EndLoc,
7025 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7026 if (!AStmt)
7027 return StmtError();
7028
7029 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7030 // 1.2.2 OpenMP Language Terminology
7031 // Structured block - An executable statement with a single entry at the
7032 // top and a single exit at the bottom.
7033 // The point of exit cannot be a branch out of the structured block.
7034 // longjmp() and throw() must not violate the entry/exit criteria.
7035 CS->getCapturedDecl()->setNothrow();
7036 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7037 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7038 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7039 // 1.2.2 OpenMP Language Terminology
7040 // Structured block - An executable statement with a single entry at the
7041 // top and a single exit at the bottom.
7042 // The point of exit cannot be a branch out of the structured block.
7043 // longjmp() and throw() must not violate the entry/exit criteria.
7044 CS->getCapturedDecl()->setNothrow();
7045 }
7046
7047 OMPLoopDirective::HelperExprs B;
7048 // In presence of clause 'collapse' with number of loops, it will
7049 // define the nested loops number.
7050 unsigned NestedLoopCount =
7051 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7052 nullptr /*ordered not a clause on distribute*/, CS, *this,
7053 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
7054 if (NestedLoopCount == 0)
7055 return StmtError();
7056
7057 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7058, __extension__ __PRETTY_FUNCTION__))
7058 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7058, __extension__ __PRETTY_FUNCTION__))
;
7059
7060 if (!CurContext->isDependentContext()) {
7061 // Finalize the clauses that need pre-built expressions for CodeGen.
7062 for (auto C : Clauses) {
7063 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7064 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7065 B.NumIterations, *this, CurScope,
7066 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7067 return StmtError();
7068 }
7069 }
7070
7071 if (checkSimdlenSafelenSpecified(*this, Clauses))
7072 return StmtError();
7073
7074 getCurFunction()->setHasBranchProtectedScope();
7075 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7076 NestedLoopCount, Clauses, AStmt, B);
7077}
7078
7079StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
7080 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7081 SourceLocation EndLoc,
7082 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7083 if (!AStmt)
7084 return StmtError();
7085
7086 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7087 // 1.2.2 OpenMP Language Terminology
7088 // Structured block - An executable statement with a single entry at the
7089 // top and a single exit at the bottom.
7090 // The point of exit cannot be a branch out of the structured block.
7091 // longjmp() and throw() must not violate the entry/exit criteria.
7092 CS->getCapturedDecl()->setNothrow();
7093 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7094 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7095 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7096 // 1.2.2 OpenMP Language Terminology
7097 // Structured block - An executable statement with a single entry at the
7098 // top and a single exit at the bottom.
7099 // The point of exit cannot be a branch out of the structured block.
7100 // longjmp() and throw() must not violate the entry/exit criteria.
7101 CS->getCapturedDecl()->setNothrow();
7102 }
7103
7104 OMPLoopDirective::HelperExprs B;
7105 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7106 // define the nested loops number.
7107 unsigned NestedLoopCount = CheckOpenMPLoop(
7108 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7109 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7110 VarsWithImplicitDSA, B);
7111 if (NestedLoopCount == 0)
7112 return StmtError();
7113
7114 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7115, __extension__ __PRETTY_FUNCTION__))
7115 "omp target parallel for simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target parallel for simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target parallel for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7115, __extension__ __PRETTY_FUNCTION__))
;
7116
7117 if (!CurContext->isDependentContext()) {
7118 // Finalize the clauses that need pre-built expressions for CodeGen.
7119 for (auto C : Clauses) {
7120 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7121 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7122 B.NumIterations, *this, CurScope,
7123 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7124 return StmtError();
7125 }
7126 }
7127 if (checkSimdlenSafelenSpecified(*this, Clauses))
7128 return StmtError();
7129
7130 getCurFunction()->setHasBranchProtectedScope();
7131 return OMPTargetParallelForSimdDirective::Create(
7132 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7133}
7134
7135StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7136 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7137 SourceLocation EndLoc,
7138 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7139 if (!AStmt)
7140 return StmtError();
7141
7142 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7143 // 1.2.2 OpenMP Language Terminology
7144 // Structured block - An executable statement with a single entry at the
7145 // top and a single exit at the bottom.
7146 // The point of exit cannot be a branch out of the structured block.
7147 // longjmp() and throw() must not violate the entry/exit criteria.
7148 CS->getCapturedDecl()->setNothrow();
7149 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7150 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7151 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7152 // 1.2.2 OpenMP Language Terminology
7153 // Structured block - An executable statement with a single entry at the
7154 // top and a single exit at the bottom.
7155 // The point of exit cannot be a branch out of the structured block.
7156 // longjmp() and throw() must not violate the entry/exit criteria.
7157 CS->getCapturedDecl()->setNothrow();
7158 }
7159
7160 OMPLoopDirective::HelperExprs B;
7161 // In presence of clause 'collapse' with number of loops, it will define the
7162 // nested loops number.
7163 unsigned NestedLoopCount =
7164 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7165 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7166 VarsWithImplicitDSA, B);
7167 if (NestedLoopCount == 0)
7168 return StmtError();
7169
7170 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7171, __extension__ __PRETTY_FUNCTION__))
7171 "omp target simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7171, __extension__ __PRETTY_FUNCTION__))
;
7172
7173 if (!CurContext->isDependentContext()) {
7174 // Finalize the clauses that need pre-built expressions for CodeGen.
7175 for (auto C : Clauses) {
7176 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7177 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7178 B.NumIterations, *this, CurScope,
7179 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7180 return StmtError();
7181 }
7182 }
7183
7184 if (checkSimdlenSafelenSpecified(*this, Clauses))
7185 return StmtError();
7186
7187 getCurFunction()->setHasBranchProtectedScope();
7188 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7189 NestedLoopCount, Clauses, AStmt, B);
7190}
7191
7192StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7193 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7194 SourceLocation EndLoc,
7195 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7196 if (!AStmt)
7197 return StmtError();
7198
7199 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7200 // 1.2.2 OpenMP Language Terminology
7201 // Structured block - An executable statement with a single entry at the
7202 // top and a single exit at the bottom.
7203 // The point of exit cannot be a branch out of the structured block.
7204 // longjmp() and throw() must not violate the entry/exit criteria.
7205 CS->getCapturedDecl()->setNothrow();
7206 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7207 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7208 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7209 // 1.2.2 OpenMP Language Terminology
7210 // Structured block - An executable statement with a single entry at the
7211 // top and a single exit at the bottom.
7212 // The point of exit cannot be a branch out of the structured block.
7213 // longjmp() and throw() must not violate the entry/exit criteria.
7214 CS->getCapturedDecl()->setNothrow();
7215 }
7216
7217 OMPLoopDirective::HelperExprs B;
7218 // In presence of clause 'collapse' with number of loops, it will
7219 // define the nested loops number.
7220 unsigned NestedLoopCount =
7221 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7222 nullptr /*ordered not a clause on distribute*/, CS, *this,
7223 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
7224 if (NestedLoopCount == 0)
7225 return StmtError();
7226
7227 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7228, __extension__ __PRETTY_FUNCTION__))
7228 "omp teams distribute loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7228, __extension__ __PRETTY_FUNCTION__))
;
7229
7230 getCurFunction()->setHasBranchProtectedScope();
7231
7232 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7233
7234 return OMPTeamsDistributeDirective::Create(
7235 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7236}
7237
7238StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7239 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7240 SourceLocation EndLoc,
7241 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7242 if (!AStmt)
7243 return StmtError();
7244
7245 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7246 // 1.2.2 OpenMP Language Terminology
7247 // Structured block - An executable statement with a single entry at the
7248 // top and a single exit at the bottom.
7249 // The point of exit cannot be a branch out of the structured block.
7250 // longjmp() and throw() must not violate the entry/exit criteria.
7251 CS->getCapturedDecl()->setNothrow();
7252 for (int ThisCaptureLevel =
7253 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7254 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7255 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7256 // 1.2.2 OpenMP Language Terminology
7257 // Structured block - An executable statement with a single entry at the
7258 // top and a single exit at the bottom.
7259 // The point of exit cannot be a branch out of the structured block.
7260 // longjmp() and throw() must not violate the entry/exit criteria.
7261 CS->getCapturedDecl()->setNothrow();
7262 }
7263
7264
7265 OMPLoopDirective::HelperExprs B;
7266 // In presence of clause 'collapse' with number of loops, it will
7267 // define the nested loops number.
7268 unsigned NestedLoopCount = CheckOpenMPLoop(
7269 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7270 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7271 VarsWithImplicitDSA, B);
7272
7273 if (NestedLoopCount == 0)
7274 return StmtError();
7275
7276 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7277, __extension__ __PRETTY_FUNCTION__))
7277 "omp teams distribute simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7277, __extension__ __PRETTY_FUNCTION__))
;
7278
7279 if (!CurContext->isDependentContext()) {
7280 // Finalize the clauses that need pre-built expressions for CodeGen.
7281 for (auto C : Clauses) {
7282 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7283 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7284 B.NumIterations, *this, CurScope,
7285 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7286 return StmtError();
7287 }
7288 }
7289
7290 if (checkSimdlenSafelenSpecified(*this, Clauses))
7291 return StmtError();
7292
7293 getCurFunction()->setHasBranchProtectedScope();
7294
7295 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7296
7297 return OMPTeamsDistributeSimdDirective::Create(
7298 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7299}
7300
7301StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7302 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7303 SourceLocation EndLoc,
7304 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7305 if (!AStmt)
7306 return StmtError();
7307
7308 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7309 // 1.2.2 OpenMP Language Terminology
7310 // Structured block - An executable statement with a single entry at the
7311 // top and a single exit at the bottom.
7312 // The point of exit cannot be a branch out of the structured block.
7313 // longjmp() and throw() must not violate the entry/exit criteria.
7314 CS->getCapturedDecl()->setNothrow();
7315
7316 for (int ThisCaptureLevel =
7317 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7318 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7319 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7320 // 1.2.2 OpenMP Language Terminology
7321 // Structured block - An executable statement with a single entry at the
7322 // top and a single exit at the bottom.
7323 // The point of exit cannot be a branch out of the structured block.
7324 // longjmp() and throw() must not violate the entry/exit criteria.
7325 CS->getCapturedDecl()->setNothrow();
7326 }
7327
7328 OMPLoopDirective::HelperExprs B;
7329 // In presence of clause 'collapse' with number of loops, it will
7330 // define the nested loops number.
7331 auto NestedLoopCount = CheckOpenMPLoop(
7332 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7333 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7334 VarsWithImplicitDSA, B);
7335
7336 if (NestedLoopCount == 0)
7337 return StmtError();
7338
7339 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7340, __extension__ __PRETTY_FUNCTION__))
7340 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7340, __extension__ __PRETTY_FUNCTION__))
;
7341
7342 if (!CurContext->isDependentContext()) {
7343 // Finalize the clauses that need pre-built expressions for CodeGen.
7344 for (auto C : Clauses) {
7345 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7346 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7347 B.NumIterations, *this, CurScope,
7348 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7349 return StmtError();
7350 }
7351 }
7352
7353 if (checkSimdlenSafelenSpecified(*this, Clauses))
7354 return StmtError();
7355
7356 getCurFunction()->setHasBranchProtectedScope();
7357
7358 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7359
7360 return OMPTeamsDistributeParallelForSimdDirective::Create(
7361 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7362}
7363
7364StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7365 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7366 SourceLocation EndLoc,
7367 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7368 if (!AStmt)
7369 return StmtError();
7370
7371 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7372 // 1.2.2 OpenMP Language Terminology
7373 // Structured block - An executable statement with a single entry at the
7374 // top and a single exit at the bottom.
7375 // The point of exit cannot be a branch out of the structured block.
7376 // longjmp() and throw() must not violate the entry/exit criteria.
7377 CS->getCapturedDecl()->setNothrow();
7378
7379 for (int ThisCaptureLevel =
7380 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7381 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7382 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7383 // 1.2.2 OpenMP Language Terminology
7384 // Structured block - An executable statement with a single entry at the
7385 // top and a single exit at the bottom.
7386 // The point of exit cannot be a branch out of the structured block.
7387 // longjmp() and throw() must not violate the entry/exit criteria.
7388 CS->getCapturedDecl()->setNothrow();
7389 }
7390
7391 OMPLoopDirective::HelperExprs B;
7392 // In presence of clause 'collapse' with number of loops, it will
7393 // define the nested loops number.
7394 unsigned NestedLoopCount = CheckOpenMPLoop(
7395 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7396 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7397 VarsWithImplicitDSA, B);
7398
7399 if (NestedLoopCount == 0)
7400 return StmtError();
7401
7402 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7403, __extension__ __PRETTY_FUNCTION__))
7403 "omp for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7403, __extension__ __PRETTY_FUNCTION__))
;
7404
7405 getCurFunction()->setHasBranchProtectedScope();
7406
7407 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7408
7409 return OMPTeamsDistributeParallelForDirective::Create(
7410 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7411 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7412}
7413
7414StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7415 Stmt *AStmt,
7416 SourceLocation StartLoc,
7417 SourceLocation EndLoc) {
7418 if (!AStmt)
7419 return StmtError();
7420
7421 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7422 // 1.2.2 OpenMP Language Terminology
7423 // Structured block - An executable statement with a single entry at the
7424 // top and a single exit at the bottom.
7425 // The point of exit cannot be a branch out of the structured block.
7426 // longjmp() and throw() must not violate the entry/exit criteria.
7427 CS->getCapturedDecl()->setNothrow();
7428
7429 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7430 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7431 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7432 // 1.2.2 OpenMP Language Terminology
7433 // Structured block - An executable statement with a single entry at the
7434 // top and a single exit at the bottom.
7435 // The point of exit cannot be a branch out of the structured block.
7436 // longjmp() and throw() must not violate the entry/exit criteria.
7437 CS->getCapturedDecl()->setNothrow();
7438 }
7439 getCurFunction()->setHasBranchProtectedScope();
7440
7441 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7442 AStmt);
7443}
7444
7445StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7446 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7447 SourceLocation EndLoc,
7448 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7449 if (!AStmt)
7450 return StmtError();
7451
7452 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7453 // 1.2.2 OpenMP Language Terminology
7454 // Structured block - An executable statement with a single entry at the
7455 // top and a single exit at the bottom.
7456 // The point of exit cannot be a branch out of the structured block.
7457 // longjmp() and throw() must not violate the entry/exit criteria.
7458 CS->getCapturedDecl()->setNothrow();
7459 for (int ThisCaptureLevel =
7460 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7461 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7462 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7463 // 1.2.2 OpenMP Language Terminology
7464 // Structured block - An executable statement with a single entry at the
7465 // top and a single exit at the bottom.
7466 // The point of exit cannot be a branch out of the structured block.
7467 // longjmp() and throw() must not violate the entry/exit criteria.
7468 CS->getCapturedDecl()->setNothrow();
7469 }
7470
7471 OMPLoopDirective::HelperExprs B;
7472 // In presence of clause 'collapse' with number of loops, it will
7473 // define the nested loops number.
7474 auto NestedLoopCount = CheckOpenMPLoop(
7475 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7476 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7477 VarsWithImplicitDSA, B);
7478 if (NestedLoopCount == 0)
7479 return StmtError();
7480
7481 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7482, __extension__ __PRETTY_FUNCTION__))
7482 "omp target teams distribute loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7482, __extension__ __PRETTY_FUNCTION__))
;
7483
7484 getCurFunction()->setHasBranchProtectedScope();
7485 return OMPTargetTeamsDistributeDirective::Create(
7486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7487}
7488
7489StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
7490 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7491 SourceLocation EndLoc,
7492 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7493 if (!AStmt)
7494 return StmtError();
7495
7496 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7497 // 1.2.2 OpenMP Language Terminology
7498 // Structured block - An executable statement with a single entry at the
7499 // top and a single exit at the bottom.
7500 // The point of exit cannot be a branch out of the structured block.
7501 // longjmp() and throw() must not violate the entry/exit criteria.
7502 CS->getCapturedDecl()->setNothrow();
7503 for (int ThisCaptureLevel =
7504 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
7505 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7506 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7507 // 1.2.2 OpenMP Language Terminology
7508 // Structured block - An executable statement with a single entry at the
7509 // top and a single exit at the bottom.
7510 // The point of exit cannot be a branch out of the structured block.
7511 // longjmp() and throw() must not violate the entry/exit criteria.
7512 CS->getCapturedDecl()->setNothrow();
7513 }
7514
7515 OMPLoopDirective::HelperExprs B;
7516 // In presence of clause 'collapse' with number of loops, it will
7517 // define the nested loops number.
7518 auto NestedLoopCount = CheckOpenMPLoop(
7519 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7520 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7521 VarsWithImplicitDSA, B);
7522 if (NestedLoopCount == 0)
7523 return StmtError();
7524
7525 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7526, __extension__ __PRETTY_FUNCTION__))
7526 "omp target teams distribute parallel for loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7526, __extension__ __PRETTY_FUNCTION__))
;
7527
7528 if (!CurContext->isDependentContext()) {
7529 // Finalize the clauses that need pre-built expressions for CodeGen.
7530 for (auto C : Clauses) {
7531 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7532 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7533 B.NumIterations, *this, CurScope,
7534 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7535 return StmtError();
7536 }
7537 }
7538
7539 getCurFunction()->setHasBranchProtectedScope();
7540 return OMPTargetTeamsDistributeParallelForDirective::Create(
7541 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7542 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7543}
7544
7545StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
7546 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7547 SourceLocation EndLoc,
7548 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7549 if (!AStmt)
7550 return StmtError();
7551
7552 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7553 // 1.2.2 OpenMP Language Terminology
7554 // Structured block - An executable statement with a single entry at the
7555 // top and a single exit at the bottom.
7556 // The point of exit cannot be a branch out of the structured block.
7557 // longjmp() and throw() must not violate the entry/exit criteria.
7558 CS->getCapturedDecl()->setNothrow();
7559 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
7560 OMPD_target_teams_distribute_parallel_for_simd);
7561 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7562 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7563 // 1.2.2 OpenMP Language Terminology
7564 // Structured block - An executable statement with a single entry at the
7565 // top and a single exit at the bottom.
7566 // The point of exit cannot be a branch out of the structured block.
7567 // longjmp() and throw() must not violate the entry/exit criteria.
7568 CS->getCapturedDecl()->setNothrow();
7569 }
7570
7571 OMPLoopDirective::HelperExprs B;
7572 // In presence of clause 'collapse' with number of loops, it will
7573 // define the nested loops number.
7574 auto NestedLoopCount =
7575 CheckOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
7576 getCollapseNumberExpr(Clauses),
7577 nullptr /*ordered not a clause on distribute*/, CS, *this,
7578 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
7579 if (NestedLoopCount == 0)
7580 return StmtError();
7581
7582 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7584, __extension__ __PRETTY_FUNCTION__))
7583 "omp target teams distribute parallel for simd loop exprs were not "(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7584, __extension__ __PRETTY_FUNCTION__))
7584 "built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute parallel for simd loop exprs were not "
"built") ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute parallel for simd loop exprs were not \" \"built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7584, __extension__ __PRETTY_FUNCTION__))
;
7585
7586 if (!CurContext->isDependentContext()) {
7587 // Finalize the clauses that need pre-built expressions for CodeGen.
7588 for (auto C : Clauses) {
7589 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7590 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7591 B.NumIterations, *this, CurScope,
7592 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7593 return StmtError();
7594 }
7595 }
7596
7597 if (checkSimdlenSafelenSpecified(*this, Clauses))
7598 return StmtError();
7599
7600 getCurFunction()->setHasBranchProtectedScope();
7601 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
7602 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7603}
7604
7605StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
7606 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7607 SourceLocation EndLoc,
7608 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7609 if (!AStmt)
7610 return StmtError();
7611
7612 auto *CS = cast<CapturedStmt>(AStmt);
7613 // 1.2.2 OpenMP Language Terminology
7614 // Structured block - An executable statement with a single entry at the
7615 // top and a single exit at the bottom.
7616 // The point of exit cannot be a branch out of the structured block.
7617 // longjmp() and throw() must not violate the entry/exit criteria.
7618 CS->getCapturedDecl()->setNothrow();
7619 for (int ThisCaptureLevel =
7620 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7621 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7622 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7623 // 1.2.2 OpenMP Language Terminology
7624 // Structured block - An executable statement with a single entry at the
7625 // top and a single exit at the bottom.
7626 // The point of exit cannot be a branch out of the structured block.
7627 // longjmp() and throw() must not violate the entry/exit criteria.
7628 CS->getCapturedDecl()->setNothrow();
7629 }
7630
7631 OMPLoopDirective::HelperExprs B;
7632 // In presence of clause 'collapse' with number of loops, it will
7633 // define the nested loops number.
7634 auto NestedLoopCount = CheckOpenMPLoop(
7635 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7636 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7637 VarsWithImplicitDSA, B);
7638 if (NestedLoopCount == 0)
7639 return StmtError();
7640
7641 assert((CurContext->isDependentContext() || B.builtAll()) &&(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7642, __extension__ __PRETTY_FUNCTION__))
7642 "omp target teams distribute simd loop exprs were not built")(static_cast <bool> ((CurContext->isDependentContext
() || B.builtAll()) && "omp target teams distribute simd loop exprs were not built"
) ? void (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp target teams distribute simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7642, __extension__ __PRETTY_FUNCTION__))
;
7643
7644 if (!CurContext->isDependentContext()) {
7645 // Finalize the clauses that need pre-built expressions for CodeGen.
7646 for (auto C : Clauses) {
7647 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7648 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7649 B.NumIterations, *this, CurScope,
7650 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7651 return StmtError();
7652 }
7653 }
7654
7655 if (checkSimdlenSafelenSpecified(*this, Clauses))
7656 return StmtError();
7657
7658 getCurFunction()->setHasBranchProtectedScope();
7659 return OMPTargetTeamsDistributeSimdDirective::Create(
7660 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7661}
7662
7663OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
7664 SourceLocation StartLoc,
7665 SourceLocation LParenLoc,
7666 SourceLocation EndLoc) {
7667 OMPClause *Res = nullptr;
7668 switch (Kind) {
7669 case OMPC_final:
7670 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7671 break;
7672 case OMPC_num_threads:
7673 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7674 break;
7675 case OMPC_safelen:
7676 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7677 break;
7678 case OMPC_simdlen:
7679 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7680 break;
7681 case OMPC_collapse:
7682 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7683 break;
7684 case OMPC_ordered:
7685 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7686 break;
7687 case OMPC_device:
7688 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7689 break;
7690 case OMPC_num_teams:
7691 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7692 break;
7693 case OMPC_thread_limit:
7694 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7695 break;
7696 case OMPC_priority:
7697 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7698 break;
7699 case OMPC_grainsize:
7700 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7701 break;
7702 case OMPC_num_tasks:
7703 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7704 break;
7705 case OMPC_hint:
7706 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7707 break;
7708 case OMPC_if:
7709 case OMPC_default:
7710 case OMPC_proc_bind:
7711 case OMPC_schedule:
7712 case OMPC_private:
7713 case OMPC_firstprivate:
7714 case OMPC_lastprivate:
7715 case OMPC_shared:
7716 case OMPC_reduction:
7717 case OMPC_task_reduction:
7718 case OMPC_in_reduction:
7719 case OMPC_linear:
7720 case OMPC_aligned:
7721 case OMPC_copyin:
7722 case OMPC_copyprivate:
7723 case OMPC_nowait:
7724 case OMPC_untied:
7725 case OMPC_mergeable:
7726 case OMPC_threadprivate:
7727 case OMPC_flush:
7728 case OMPC_read:
7729 case OMPC_write:
7730 case OMPC_update:
7731 case OMPC_capture:
7732 case OMPC_seq_cst:
7733 case OMPC_depend:
7734 case OMPC_threads:
7735 case OMPC_simd:
7736 case OMPC_map:
7737 case OMPC_nogroup:
7738 case OMPC_dist_schedule:
7739 case OMPC_defaultmap:
7740 case OMPC_unknown:
7741 case OMPC_uniform:
7742 case OMPC_to:
7743 case OMPC_from:
7744 case OMPC_use_device_ptr:
7745 case OMPC_is_device_ptr:
7746 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7746)
;
7747 }
7748 return Res;
7749}
7750
7751// An OpenMP directive such as 'target parallel' has two captured regions:
7752// for the 'target' and 'parallel' respectively. This function returns
7753// the region in which to capture expressions associated with a clause.
7754// A return value of OMPD_unknown signifies that the expression should not
7755// be captured.
7756static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
7757 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
7758 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7759 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7760 switch (CKind) {
7761 case OMPC_if:
7762 switch (DKind) {
7763 case OMPD_target_parallel:
7764 case OMPD_target_parallel_for:
7765 case OMPD_target_parallel_for_simd:
7766 // If this clause applies to the nested 'parallel' region, capture within
7767 // the 'target' region, otherwise do not capture.
7768 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7769 CaptureRegion = OMPD_target;
7770 break;
7771 case OMPD_target_teams_distribute_parallel_for:
7772 case OMPD_target_teams_distribute_parallel_for_simd:
7773 // If this clause applies to the nested 'parallel' region, capture within
7774 // the 'teams' region, otherwise do not capture.
7775 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7776 CaptureRegion = OMPD_teams;
7777 break;
7778 case OMPD_teams_distribute_parallel_for:
7779 case OMPD_teams_distribute_parallel_for_simd:
7780 CaptureRegion = OMPD_teams;
7781 break;
7782 case OMPD_target_update:
7783 case OMPD_target_enter_data:
7784 case OMPD_target_exit_data:
7785 CaptureRegion = OMPD_task;
7786 break;
7787 case OMPD_cancel:
7788 case OMPD_parallel:
7789 case OMPD_parallel_sections:
7790 case OMPD_parallel_for:
7791 case OMPD_parallel_for_simd:
7792 case OMPD_target:
7793 case OMPD_target_simd:
7794 case OMPD_target_teams:
7795 case OMPD_target_teams_distribute:
7796 case OMPD_target_teams_distribute_simd:
7797 case OMPD_distribute_parallel_for:
7798 case OMPD_distribute_parallel_for_simd:
7799 case OMPD_task:
7800 case OMPD_taskloop:
7801 case OMPD_taskloop_simd:
7802 case OMPD_target_data:
7803 // Do not capture if-clause expressions.
7804 break;
7805 case OMPD_threadprivate:
7806 case OMPD_taskyield:
7807 case OMPD_barrier:
7808 case OMPD_taskwait:
7809 case OMPD_cancellation_point:
7810 case OMPD_flush:
7811 case OMPD_declare_reduction:
7812 case OMPD_declare_simd:
7813 case OMPD_declare_target:
7814 case OMPD_end_declare_target:
7815 case OMPD_teams:
7816 case OMPD_simd:
7817 case OMPD_for:
7818 case OMPD_for_simd:
7819 case OMPD_sections:
7820 case OMPD_section:
7821 case OMPD_single:
7822 case OMPD_master:
7823 case OMPD_critical:
7824 case OMPD_taskgroup:
7825 case OMPD_distribute:
7826 case OMPD_ordered:
7827 case OMPD_atomic:
7828 case OMPD_distribute_simd:
7829 case OMPD_teams_distribute:
7830 case OMPD_teams_distribute_simd:
7831 llvm_unreachable("Unexpected OpenMP directive with if-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with if-clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7831)
;
7832 case OMPD_unknown:
7833 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7833)
;
7834 }
7835 break;
7836 case OMPC_num_threads:
7837 switch (DKind) {
7838 case OMPD_target_parallel:
7839 case OMPD_target_parallel_for:
7840 case OMPD_target_parallel_for_simd:
7841 CaptureRegion = OMPD_target;
7842 break;
7843 case OMPD_teams_distribute_parallel_for:
7844 case OMPD_teams_distribute_parallel_for_simd:
7845 case OMPD_target_teams_distribute_parallel_for:
7846 case OMPD_target_teams_distribute_parallel_for_simd:
7847 CaptureRegion = OMPD_teams;
7848 break;
7849 case OMPD_parallel:
7850 case OMPD_parallel_sections:
7851 case OMPD_parallel_for:
7852 case OMPD_parallel_for_simd:
7853 case OMPD_distribute_parallel_for:
7854 case OMPD_distribute_parallel_for_simd:
7855 // Do not capture num_threads-clause expressions.
7856 break;
7857 case OMPD_target_data:
7858 case OMPD_target_enter_data:
7859 case OMPD_target_exit_data:
7860 case OMPD_target_update:
7861 case OMPD_target:
7862 case OMPD_target_simd:
7863 case OMPD_target_teams:
7864 case OMPD_target_teams_distribute:
7865 case OMPD_target_teams_distribute_simd:
7866 case OMPD_cancel:
7867 case OMPD_task:
7868 case OMPD_taskloop:
7869 case OMPD_taskloop_simd:
7870 case OMPD_threadprivate:
7871 case OMPD_taskyield:
7872 case OMPD_barrier:
7873 case OMPD_taskwait:
7874 case OMPD_cancellation_point:
7875 case OMPD_flush:
7876 case OMPD_declare_reduction:
7877 case OMPD_declare_simd:
7878 case OMPD_declare_target:
7879 case OMPD_end_declare_target:
7880 case OMPD_teams:
7881 case OMPD_simd:
7882 case OMPD_for:
7883 case OMPD_for_simd:
7884 case OMPD_sections:
7885 case OMPD_section:
7886 case OMPD_single:
7887 case OMPD_master:
7888 case OMPD_critical:
7889 case OMPD_taskgroup:
7890 case OMPD_distribute:
7891 case OMPD_ordered:
7892 case OMPD_atomic:
7893 case OMPD_distribute_simd:
7894 case OMPD_teams_distribute:
7895 case OMPD_teams_distribute_simd:
7896 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_threads-clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7896)
;
7897 case OMPD_unknown:
7898 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7898)
;
7899 }
7900 break;
7901 case OMPC_num_teams:
7902 switch (DKind) {
7903 case OMPD_target_teams:
7904 case OMPD_target_teams_distribute:
7905 case OMPD_target_teams_distribute_simd:
7906 case OMPD_target_teams_distribute_parallel_for:
7907 case OMPD_target_teams_distribute_parallel_for_simd:
7908 CaptureRegion = OMPD_target;
7909 break;
7910 case OMPD_teams_distribute_parallel_for:
7911 case OMPD_teams_distribute_parallel_for_simd:
7912 case OMPD_teams:
7913 case OMPD_teams_distribute:
7914 case OMPD_teams_distribute_simd:
7915 // Do not capture num_teams-clause expressions.
7916 break;
7917 case OMPD_distribute_parallel_for:
7918 case OMPD_distribute_parallel_for_simd:
7919 case OMPD_task:
7920 case OMPD_taskloop:
7921 case OMPD_taskloop_simd:
7922 case OMPD_target_data:
7923 case OMPD_target_enter_data:
7924 case OMPD_target_exit_data:
7925 case OMPD_target_update:
7926 case OMPD_cancel:
7927 case OMPD_parallel:
7928 case OMPD_parallel_sections:
7929 case OMPD_parallel_for:
7930 case OMPD_parallel_for_simd:
7931 case OMPD_target:
7932 case OMPD_target_simd:
7933 case OMPD_target_parallel:
7934 case OMPD_target_parallel_for:
7935 case OMPD_target_parallel_for_simd:
7936 case OMPD_threadprivate:
7937 case OMPD_taskyield:
7938 case OMPD_barrier:
7939 case OMPD_taskwait:
7940 case OMPD_cancellation_point:
7941 case OMPD_flush:
7942 case OMPD_declare_reduction:
7943 case OMPD_declare_simd:
7944 case OMPD_declare_target:
7945 case OMPD_end_declare_target:
7946 case OMPD_simd:
7947 case OMPD_for:
7948 case OMPD_for_simd:
7949 case OMPD_sections:
7950 case OMPD_section:
7951 case OMPD_single:
7952 case OMPD_master:
7953 case OMPD_critical:
7954 case OMPD_taskgroup:
7955 case OMPD_distribute:
7956 case OMPD_ordered:
7957 case OMPD_atomic:
7958 case OMPD_distribute_simd:
7959 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7959)
;
7960 case OMPD_unknown:
7961 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7961)
;
7962 }
7963 break;
7964 case OMPC_thread_limit:
7965 switch (DKind) {
7966 case OMPD_target_teams:
7967 case OMPD_target_teams_distribute:
7968 case OMPD_target_teams_distribute_simd:
7969 case OMPD_target_teams_distribute_parallel_for:
7970 case OMPD_target_teams_distribute_parallel_for_simd:
7971 CaptureRegion = OMPD_target;
7972 break;
7973 case OMPD_teams_distribute_parallel_for:
7974 case OMPD_teams_distribute_parallel_for_simd:
7975 case OMPD_teams:
7976 case OMPD_teams_distribute:
7977 case OMPD_teams_distribute_simd:
7978 // Do not capture thread_limit-clause expressions.
7979 break;
7980 case OMPD_distribute_parallel_for:
7981 case OMPD_distribute_parallel_for_simd:
7982 case OMPD_task:
7983 case OMPD_taskloop:
7984 case OMPD_taskloop_simd:
7985 case OMPD_target_data:
7986 case OMPD_target_enter_data:
7987 case OMPD_target_exit_data:
7988 case OMPD_target_update:
7989 case OMPD_cancel:
7990 case OMPD_parallel:
7991 case OMPD_parallel_sections:
7992 case OMPD_parallel_for:
7993 case OMPD_parallel_for_simd:
7994 case OMPD_target:
7995 case OMPD_target_simd:
7996 case OMPD_target_parallel:
7997 case OMPD_target_parallel_for:
7998 case OMPD_target_parallel_for_simd:
7999 case OMPD_threadprivate:
8000 case OMPD_taskyield:
8001 case OMPD_barrier:
8002 case OMPD_taskwait:
8003 case OMPD_cancellation_point:
8004 case OMPD_flush:
8005 case OMPD_declare_reduction:
8006 case OMPD_declare_simd:
8007 case OMPD_declare_target:
8008 case OMPD_end_declare_target:
8009 case OMPD_simd:
8010 case OMPD_for:
8011 case OMPD_for_simd:
8012 case OMPD_sections:
8013 case OMPD_section:
8014 case OMPD_single:
8015 case OMPD_master:
8016 case OMPD_critical:
8017 case OMPD_taskgroup:
8018 case OMPD_distribute:
8019 case OMPD_ordered:
8020 case OMPD_atomic:
8021 case OMPD_distribute_simd:
8022 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with thread_limit-clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8022)
;
8023 case OMPD_unknown:
8024 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8024)
;
8025 }
8026 break;
8027 case OMPC_schedule:
8028 switch (DKind) {
8029 case OMPD_parallel_for:
8030 case OMPD_parallel_for_simd:
8031 case OMPD_distribute_parallel_for:
8032 case OMPD_distribute_parallel_for_simd:
8033 case OMPD_teams_distribute_parallel_for:
8034 case OMPD_teams_distribute_parallel_for_simd:
8035 case OMPD_target_parallel_for:
8036 case OMPD_target_parallel_for_simd:
8037 case OMPD_target_teams_distribute_parallel_for:
8038 case OMPD_target_teams_distribute_parallel_for_simd:
8039 CaptureRegion = OMPD_parallel;
8040 break;
8041 case OMPD_for:
8042 case OMPD_for_simd:
8043 // Do not capture schedule-clause expressions.
8044 break;
8045 case OMPD_task:
8046 case OMPD_taskloop:
8047 case OMPD_taskloop_simd:
8048 case OMPD_target_data:
8049 case OMPD_target_enter_data:
8050 case OMPD_target_exit_data:
8051 case OMPD_target_update:
8052 case OMPD_teams:
8053 case OMPD_teams_distribute:
8054 case OMPD_teams_distribute_simd:
8055 case OMPD_target_teams_distribute:
8056 case OMPD_target_teams_distribute_simd:
8057 case OMPD_target:
8058 case OMPD_target_simd:
8059 case OMPD_target_parallel:
8060 case OMPD_cancel:
8061 case OMPD_parallel:
8062 case OMPD_parallel_sections:
8063 case OMPD_threadprivate:
8064 case OMPD_taskyield:
8065 case OMPD_barrier:
8066 case OMPD_taskwait:
8067 case OMPD_cancellation_point:
8068 case OMPD_flush:
8069 case OMPD_declare_reduction:
8070 case OMPD_declare_simd:
8071 case OMPD_declare_target:
8072 case OMPD_end_declare_target:
8073 case OMPD_simd:
8074 case OMPD_sections:
8075 case OMPD_section:
8076 case OMPD_single:
8077 case OMPD_master:
8078 case OMPD_critical:
8079 case OMPD_taskgroup:
8080 case OMPD_distribute:
8081 case OMPD_ordered:
8082 case OMPD_atomic:
8083 case OMPD_distribute_simd:
8084 case OMPD_target_teams:
8085 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8085)
;
8086 case OMPD_unknown:
8087 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8087)
;
8088 }
8089 break;
8090 case OMPC_dist_schedule:
8091 switch (DKind) {
8092 case OMPD_teams_distribute_parallel_for:
8093 case OMPD_teams_distribute_parallel_for_simd:
8094 case OMPD_teams_distribute:
8095 case OMPD_teams_distribute_simd:
8096 case OMPD_target_teams_distribute_parallel_for:
8097 case OMPD_target_teams_distribute_parallel_for_simd:
8098 case OMPD_target_teams_distribute:
8099 case OMPD_target_teams_distribute_simd:
8100 CaptureRegion = OMPD_teams;
8101 break;
8102 case OMPD_distribute_parallel_for:
8103 case OMPD_distribute_parallel_for_simd:
8104 case OMPD_distribute:
8105 case OMPD_distribute_simd:
8106 // Do not capture thread_limit-clause expressions.
8107 break;
8108 case OMPD_parallel_for:
8109 case OMPD_parallel_for_simd:
8110 case OMPD_target_parallel_for_simd:
8111 case OMPD_target_parallel_for:
8112 case OMPD_task:
8113 case OMPD_taskloop:
8114 case OMPD_taskloop_simd:
8115 case OMPD_target_data:
8116 case OMPD_target_enter_data:
8117 case OMPD_target_exit_data:
8118 case OMPD_target_update:
8119 case OMPD_teams:
8120 case OMPD_target:
8121 case OMPD_target_simd:
8122 case OMPD_target_parallel:
8123 case OMPD_cancel:
8124 case OMPD_parallel:
8125 case OMPD_parallel_sections:
8126 case OMPD_threadprivate:
8127 case OMPD_taskyield:
8128 case OMPD_barrier:
8129 case OMPD_taskwait:
8130 case OMPD_cancellation_point:
8131 case OMPD_flush:
8132 case OMPD_declare_reduction:
8133 case OMPD_declare_simd:
8134 case OMPD_declare_target:
8135 case OMPD_end_declare_target:
8136 case OMPD_simd:
8137 case OMPD_for:
8138 case OMPD_for_simd:
8139 case OMPD_sections:
8140 case OMPD_section:
8141 case OMPD_single:
8142 case OMPD_master:
8143 case OMPD_critical:
8144 case OMPD_taskgroup:
8145 case OMPD_ordered:
8146 case OMPD_atomic:
8147 case OMPD_target_teams:
8148 llvm_unreachable("Unexpected OpenMP directive with schedule clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with schedule clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8148)
;
8149 case OMPD_unknown:
8150 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8150)
;
8151 }
8152 break;
8153 case OMPC_device:
8154 switch (DKind) {
8155 case OMPD_target_update:
8156 case OMPD_target_enter_data:
8157 case OMPD_target_exit_data:
8158 case OMPD_target:
8159 case OMPD_target_simd:
8160 case OMPD_target_teams:
8161 case OMPD_target_parallel:
8162 case OMPD_target_teams_distribute:
8163 case OMPD_target_teams_distribute_simd:
8164 case OMPD_target_parallel_for:
8165 case OMPD_target_parallel_for_simd:
8166 case OMPD_target_teams_distribute_parallel_for:
8167 case OMPD_target_teams_distribute_parallel_for_simd:
8168 CaptureRegion = OMPD_task;
8169 break;
8170 case OMPD_target_data:
8171 // Do not capture device-clause expressions.
8172 break;
8173 case OMPD_teams_distribute_parallel_for:
8174 case OMPD_teams_distribute_parallel_for_simd:
8175 case OMPD_teams:
8176 case OMPD_teams_distribute:
8177 case OMPD_teams_distribute_simd:
8178 case OMPD_distribute_parallel_for:
8179 case OMPD_distribute_parallel_for_simd:
8180 case OMPD_task:
8181 case OMPD_taskloop:
8182 case OMPD_taskloop_simd:
8183 case OMPD_cancel:
8184 case OMPD_parallel:
8185 case OMPD_parallel_sections:
8186 case OMPD_parallel_for:
8187 case OMPD_parallel_for_simd:
8188 case OMPD_threadprivate:
8189 case OMPD_taskyield:
8190 case OMPD_barrier:
8191 case OMPD_taskwait:
8192 case OMPD_cancellation_point:
8193 case OMPD_flush:
8194 case OMPD_declare_reduction:
8195 case OMPD_declare_simd:
8196 case OMPD_declare_target:
8197 case OMPD_end_declare_target:
8198 case OMPD_simd:
8199 case OMPD_for:
8200 case OMPD_for_simd:
8201 case OMPD_sections:
8202 case OMPD_section:
8203 case OMPD_single:
8204 case OMPD_master:
8205 case OMPD_critical:
8206 case OMPD_taskgroup:
8207 case OMPD_distribute:
8208 case OMPD_ordered:
8209 case OMPD_atomic:
8210 case OMPD_distribute_simd:
8211 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause")::llvm::llvm_unreachable_internal("Unexpected OpenMP directive with num_teams-clause"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8211)
;
8212 case OMPD_unknown:
8213 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8213)
;
8214 }
8215 break;
8216 case OMPC_firstprivate:
8217 case OMPC_lastprivate:
8218 case OMPC_reduction:
8219 case OMPC_task_reduction:
8220 case OMPC_in_reduction:
8221 case OMPC_linear:
8222 case OMPC_default:
8223 case OMPC_proc_bind:
8224 case OMPC_final:
8225 case OMPC_safelen:
8226 case OMPC_simdlen:
8227 case OMPC_collapse:
8228 case OMPC_private:
8229 case OMPC_shared:
8230 case OMPC_aligned:
8231 case OMPC_copyin:
8232 case OMPC_copyprivate:
8233 case OMPC_ordered:
8234 case OMPC_nowait:
8235 case OMPC_untied:
8236 case OMPC_mergeable:
8237 case OMPC_threadprivate:
8238 case OMPC_flush:
8239 case OMPC_read:
8240 case OMPC_write:
8241 case OMPC_update:
8242 case OMPC_capture:
8243 case OMPC_seq_cst:
8244 case OMPC_depend:
8245 case OMPC_threads:
8246 case OMPC_simd:
8247 case OMPC_map:
8248 case OMPC_priority:
8249 case OMPC_grainsize:
8250 case OMPC_nogroup:
8251 case OMPC_num_tasks:
8252 case OMPC_hint:
8253 case OMPC_defaultmap:
8254 case OMPC_unknown:
8255 case OMPC_uniform:
8256 case OMPC_to:
8257 case OMPC_from:
8258 case OMPC_use_device_ptr:
8259 case OMPC_is_device_ptr:
8260 llvm_unreachable("Unexpected OpenMP clause.")::llvm::llvm_unreachable_internal("Unexpected OpenMP clause."
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8260)
;
8261 }
8262 return CaptureRegion;
8263}
8264
8265OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
8266 Expr *Condition, SourceLocation StartLoc,
8267 SourceLocation LParenLoc,
8268 SourceLocation NameModifierLoc,
8269 SourceLocation ColonLoc,
8270 SourceLocation EndLoc) {
8271 Expr *ValExpr = Condition;
8272 Stmt *HelperValStmt = nullptr;
8273 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8274 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8275 !Condition->isInstantiationDependent() &&
8276 !Condition->containsUnexpandedParameterPack()) {
8277 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8278 if (Val.isInvalid())
8279 return nullptr;
8280
8281 ValExpr = Val.get();
8282
8283 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8284 CaptureRegion =
8285 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8286 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8287 ValExpr = MakeFullExpr(ValExpr).get();
8288 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8289 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8290 HelperValStmt = buildPreInits(Context, Captures);
8291 }
8292 }
8293
8294 return new (Context)
8295 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8296 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8297}
8298
8299OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
8300 SourceLocation StartLoc,
8301 SourceLocation LParenLoc,
8302 SourceLocation EndLoc) {
8303 Expr *ValExpr = Condition;
8304 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8305 !Condition->isInstantiationDependent() &&
8306 !Condition->containsUnexpandedParameterPack()) {
8307 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8308 if (Val.isInvalid())
8309 return nullptr;
8310
8311 ValExpr = MakeFullExpr(Val.get()).get();
8312 }
8313
8314 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8315}
8316ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
8317 Expr *Op) {
8318 if (!Op)
8319 return ExprError();
8320
8321 class IntConvertDiagnoser : public ICEConvertDiagnoser {
8322 public:
8323 IntConvertDiagnoser()
8324 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8325 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8326 QualType T) override {
8327 return S.Diag(Loc, diag::err_omp_not_integral) << T;
8328 }
8329 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8330 QualType T) override {
8331 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8332 }
8333 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8334 QualType T,
8335 QualType ConvTy) override {
8336 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8337 }
8338 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8339 QualType ConvTy) override {
8340 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8341 << ConvTy->isEnumeralType() << ConvTy;
8342 }
8343 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8344 QualType T) override {
8345 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8346 }
8347 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8348 QualType ConvTy) override {
8349 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8350 << ConvTy->isEnumeralType() << ConvTy;
8351 }
8352 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8353 QualType) override {
8354 llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8354)
;
8355 }
8356 } ConvertDiagnoser;
8357 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8358}
8359
8360static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8361 OpenMPClauseKind CKind,
8362 bool StrictlyPositive) {
8363 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8364 !ValExpr->isInstantiationDependent()) {
8365 SourceLocation Loc = ValExpr->getExprLoc();
8366 ExprResult Value =
8367 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8368 if (Value.isInvalid())
8369 return false;
8370
8371 ValExpr = Value.get();
8372 // The expression must evaluate to a non-negative integer value.
8373 llvm::APSInt Result;
8374 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8375 Result.isSigned() &&
8376 !((!StrictlyPositive && Result.isNonNegative()) ||
8377 (StrictlyPositive && Result.isStrictlyPositive()))) {
8378 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8379 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8380 << ValExpr->getSourceRange();
8381 return false;
8382 }
8383 }
8384 return true;
8385}
8386
8387OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
8388 SourceLocation StartLoc,
8389 SourceLocation LParenLoc,
8390 SourceLocation EndLoc) {
8391 Expr *ValExpr = NumThreads;
8392 Stmt *HelperValStmt = nullptr;
8393
8394 // OpenMP [2.5, Restrictions]
8395 // The num_threads expression must evaluate to a positive integer value.
8396 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8397 /*StrictlyPositive=*/true))
8398 return nullptr;
8399
8400 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
8401 OpenMPDirectiveKind CaptureRegion =
8402 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8403 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8404 ValExpr = MakeFullExpr(ValExpr).get();
8405 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8406 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8407 HelperValStmt = buildPreInits(Context, Captures);
8408 }
8409
8410 return new (Context) OMPNumThreadsClause(
8411 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8412}
8413
8414ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8415 OpenMPClauseKind CKind,
8416 bool StrictlyPositive) {
8417 if (!E)
8418 return ExprError();
8419 if (E->isValueDependent() || E->isTypeDependent() ||
8420 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
8421 return E;
8422 llvm::APSInt Result;
8423 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8424 if (ICE.isInvalid())
8425 return ExprError();
8426 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8427 (!StrictlyPositive && !Result.isNonNegative())) {
8428 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8429 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8430 << E->getSourceRange();
8431 return ExprError();
8432 }
8433 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8434 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8435 << E->getSourceRange();
8436 return ExprError();
8437 }
8438 if (CKind == OMPC_collapse && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops() == 1)
8439 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
8440 else if (CKind == OMPC_ordered)
8441 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(Result.getExtValue());
8442 return ICE;
8443}
8444
8445OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
8446 SourceLocation LParenLoc,
8447 SourceLocation EndLoc) {
8448 // OpenMP [2.8.1, simd construct, Description]
8449 // The parameter of the safelen clause must be a constant
8450 // positive integer expression.
8451 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8452 if (Safelen.isInvalid())
8453 return nullptr;
8454 return new (Context)
8455 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8456}
8457
8458OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
8459 SourceLocation LParenLoc,
8460 SourceLocation EndLoc) {
8461 // OpenMP [2.8.1, simd construct, Description]
8462 // The parameter of the simdlen clause must be a constant
8463 // positive integer expression.
8464 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8465 if (Simdlen.isInvalid())
8466 return nullptr;
8467 return new (Context)
8468 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8469}
8470
8471OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
8472 SourceLocation StartLoc,
8473 SourceLocation LParenLoc,
8474 SourceLocation EndLoc) {
8475 // OpenMP [2.7.1, loop construct, Description]
8476 // OpenMP [2.8.1, simd construct, Description]
8477 // OpenMP [2.9.6, distribute construct, Description]
8478 // The parameter of the collapse clause must be a constant
8479 // positive integer expression.
8480 ExprResult NumForLoopsResult =
8481 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8482 if (NumForLoopsResult.isInvalid())
8483 return nullptr;
8484 return new (Context)
8485 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8486}
8487
8488OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
8489 SourceLocation EndLoc,
8490 SourceLocation LParenLoc,
8491 Expr *NumForLoops) {
8492 // OpenMP [2.7.1, loop construct, Description]
8493 // OpenMP [2.8.1, simd construct, Description]
8494 // OpenMP [2.9.6, distribute construct, Description]
8495 // The parameter of the ordered clause must be a constant
8496 // positive integer expression if any.
8497 if (NumForLoops && LParenLoc.isValid()) {
8498 ExprResult NumForLoopsResult =
8499 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8500 if (NumForLoopsResult.isInvalid())
8501 return nullptr;
8502 NumForLoops = NumForLoopsResult.get();
8503 } else
8504 NumForLoops = nullptr;
8505 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
8506 return new (Context)
8507 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
8508}
8509
8510OMPClause *Sema::ActOnOpenMPSimpleClause(
8511 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8512 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8513 OMPClause *Res = nullptr;
8514 switch (Kind) {
8515 case OMPC_default:
8516 Res =
8517 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8518 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8519 break;
8520 case OMPC_proc_bind:
8521 Res = ActOnOpenMPProcBindClause(
8522 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8523 LParenLoc, EndLoc);
8524 break;
8525 case OMPC_if:
8526 case OMPC_final:
8527 case OMPC_num_threads:
8528 case OMPC_safelen:
8529 case OMPC_simdlen:
8530 case OMPC_collapse:
8531 case OMPC_schedule:
8532 case OMPC_private:
8533 case OMPC_firstprivate:
8534 case OMPC_lastprivate:
8535 case OMPC_shared:
8536 case OMPC_reduction:
8537 case OMPC_task_reduction:
8538 case OMPC_in_reduction:
8539 case OMPC_linear:
8540 case OMPC_aligned:
8541 case OMPC_copyin:
8542 case OMPC_copyprivate:
8543 case OMPC_ordered:
8544 case OMPC_nowait:
8545 case OMPC_untied:
8546 case OMPC_mergeable:
8547 case OMPC_threadprivate:
8548 case OMPC_flush:
8549 case OMPC_read:
8550 case OMPC_write:
8551 case OMPC_update:
8552 case OMPC_capture:
8553 case OMPC_seq_cst:
8554 case OMPC_depend:
8555 case OMPC_device:
8556 case OMPC_threads:
8557 case OMPC_simd:
8558 case OMPC_map:
8559 case OMPC_num_teams:
8560 case OMPC_thread_limit:
8561 case OMPC_priority:
8562 case OMPC_grainsize:
8563 case OMPC_nogroup:
8564 case OMPC_num_tasks:
8565 case OMPC_hint:
8566 case OMPC_dist_schedule:
8567 case OMPC_defaultmap:
8568 case OMPC_unknown:
8569 case OMPC_uniform:
8570 case OMPC_to:
8571 case OMPC_from:
8572 case OMPC_use_device_ptr:
8573 case OMPC_is_device_ptr:
8574 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8574)
;
8575 }
8576 return Res;
8577}
8578
8579static std::string
8580getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
8581 ArrayRef<unsigned> Exclude = llvm::None) {
8582 std::string Values;
8583 unsigned Bound = Last >= 2 ? Last - 2 : 0;
8584 unsigned Skipped = Exclude.size();
8585 auto S = Exclude.begin(), E = Exclude.end();
8586 for (unsigned i = First; i < Last; ++i) {
8587 if (std::find(S, E, i) != E) {
8588 --Skipped;
8589 continue;
8590 }
8591 Values += "'";
8592 Values += getOpenMPSimpleClauseTypeName(K, i);
8593 Values += "'";
8594 if (i == Bound - Skipped)
8595 Values += " or ";
8596 else if (i != Bound + 1 - Skipped)
8597 Values += ", ";
8598 }
8599 return Values;
8600}
8601
8602OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
8603 SourceLocation KindKwLoc,
8604 SourceLocation StartLoc,
8605 SourceLocation LParenLoc,
8606 SourceLocation EndLoc) {
8607 if (Kind == OMPC_DEFAULT_unknown) {
8608 static_assert(OMPC_DEFAULT_unknown > 0,
8609 "OMPC_DEFAULT_unknown not greater than 0");
8610 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8611 << getListOfPossibleValues(OMPC_default, /*First=*/0,
8612 /*Last=*/OMPC_DEFAULT_unknown)
8613 << getOpenMPClauseName(OMPC_default);
8614 return nullptr;
8615 }
8616 switch (Kind) {
8617 case OMPC_DEFAULT_none:
8618 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSANone(KindKwLoc);
8619 break;
8620 case OMPC_DEFAULT_shared:
8621 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDSAShared(KindKwLoc);
8622 break;
8623 case OMPC_DEFAULT_unknown:
8624 llvm_unreachable("Clause kind is not allowed.")::llvm::llvm_unreachable_internal("Clause kind is not allowed."
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8624)
;
8625 break;
8626 }
8627 return new (Context)
8628 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8629}
8630
8631OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
8632 SourceLocation KindKwLoc,
8633 SourceLocation StartLoc,
8634 SourceLocation LParenLoc,
8635 SourceLocation EndLoc) {
8636 if (Kind == OMPC_PROC_BIND_unknown) {
8637 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8638 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8639 /*Last=*/OMPC_PROC_BIND_unknown)
8640 << getOpenMPClauseName(OMPC_proc_bind);
8641 return nullptr;
8642 }
8643 return new (Context)
8644 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8645}
8646
8647OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
8648 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
8649 SourceLocation StartLoc, SourceLocation LParenLoc,
8650 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8651 SourceLocation EndLoc) {
8652 OMPClause *Res = nullptr;
8653 switch (Kind) {
8654 case OMPC_schedule:
8655 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8656 assert(Argument.size() == NumberOfElements &&(static_cast <bool> (Argument.size() == NumberOfElements
&& ArgumentLoc.size() == NumberOfElements) ? void (0
) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8657, __extension__ __PRETTY_FUNCTION__))
8657 ArgumentLoc.size() == NumberOfElements)(static_cast <bool> (Argument.size() == NumberOfElements
&& ArgumentLoc.size() == NumberOfElements) ? void (0
) : __assert_fail ("Argument.size() == NumberOfElements && ArgumentLoc.size() == NumberOfElements"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8657, __extension__ __PRETTY_FUNCTION__))
;
8658 Res = ActOnOpenMPScheduleClause(
8659 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8660 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8661 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8662 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8663 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8664 break;
8665 case OMPC_if:
8666 assert(Argument.size() == 1 && ArgumentLoc.size() == 1)(static_cast <bool> (Argument.size() == 1 && ArgumentLoc
.size() == 1) ? void (0) : __assert_fail ("Argument.size() == 1 && ArgumentLoc.size() == 1"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8666, __extension__ __PRETTY_FUNCTION__))
;
8667 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8668 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8669 DelimLoc, EndLoc);
8670 break;
8671 case OMPC_dist_schedule:
8672 Res = ActOnOpenMPDistScheduleClause(
8673 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8674 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8675 break;
8676 case OMPC_defaultmap:
8677 enum { Modifier, DefaultmapKind };
8678 Res = ActOnOpenMPDefaultmapClause(
8679 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8680 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8681 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8682 EndLoc);
8683 break;
8684 case OMPC_final:
8685 case OMPC_num_threads:
8686 case OMPC_safelen:
8687 case OMPC_simdlen:
8688 case OMPC_collapse:
8689 case OMPC_default:
8690 case OMPC_proc_bind:
8691 case OMPC_private:
8692 case OMPC_firstprivate:
8693 case OMPC_lastprivate:
8694 case OMPC_shared:
8695 case OMPC_reduction:
8696 case OMPC_task_reduction:
8697 case OMPC_in_reduction:
8698 case OMPC_linear:
8699 case OMPC_aligned:
8700 case OMPC_copyin:
8701 case OMPC_copyprivate:
8702 case OMPC_ordered:
8703 case OMPC_nowait:
8704 case OMPC_untied:
8705 case OMPC_mergeable:
8706 case OMPC_threadprivate:
8707 case OMPC_flush:
8708 case OMPC_read:
8709 case OMPC_write:
8710 case OMPC_update:
8711 case OMPC_capture:
8712 case OMPC_seq_cst:
8713 case OMPC_depend:
8714 case OMPC_device:
8715 case OMPC_threads:
8716 case OMPC_simd:
8717 case OMPC_map:
8718 case OMPC_num_teams:
8719 case OMPC_thread_limit:
8720 case OMPC_priority:
8721 case OMPC_grainsize:
8722 case OMPC_nogroup:
8723 case OMPC_num_tasks:
8724 case OMPC_hint:
8725 case OMPC_unknown:
8726 case OMPC_uniform:
8727 case OMPC_to:
8728 case OMPC_from:
8729 case OMPC_use_device_ptr:
8730 case OMPC_is_device_ptr:
8731 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8731)
;
8732 }
8733 return Res;
8734}
8735
8736static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
8737 OpenMPScheduleClauseModifier M2,
8738 SourceLocation M1Loc, SourceLocation M2Loc) {
8739 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8740 SmallVector<unsigned, 2> Excluded;
8741 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
8742 Excluded.push_back(M2);
8743 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8744 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8745 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8746 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8747 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8748 << getListOfPossibleValues(OMPC_schedule,
8749 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8750 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8751 Excluded)
8752 << getOpenMPClauseName(OMPC_schedule);
8753 return true;
8754 }
8755 return false;
8756}
8757
8758OMPClause *Sema::ActOnOpenMPScheduleClause(
8759 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
8760 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8761 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8762 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8763 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8764 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8765 return nullptr;
8766 // OpenMP, 2.7.1, Loop Construct, Restrictions
8767 // Either the monotonic modifier or the nonmonotonic modifier can be specified
8768 // but not both.
8769 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8770 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8771 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8772 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8773 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8774 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8775 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8776 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8777 return nullptr;
8778 }
8779 if (Kind == OMPC_SCHEDULE_unknown) {
8780 std::string Values;
8781 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8782 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8783 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8784 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8785 Exclude);
8786 } else {
8787 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8788 /*Last=*/OMPC_SCHEDULE_unknown);
8789 }
8790 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8791 << Values << getOpenMPClauseName(OMPC_schedule);
8792 return nullptr;
8793 }
8794 // OpenMP, 2.7.1, Loop Construct, Restrictions
8795 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
8796 // schedule(guided).
8797 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
8798 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
8799 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
8800 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
8801 diag::err_omp_schedule_nonmonotonic_static);
8802 return nullptr;
8803 }
8804 Expr *ValExpr = ChunkSize;
8805 Stmt *HelperValStmt = nullptr;
8806 if (ChunkSize) {
8807 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
8808 !ChunkSize->isInstantiationDependent() &&
8809 !ChunkSize->containsUnexpandedParameterPack()) {
8810 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
8811 ExprResult Val =
8812 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
8813 if (Val.isInvalid())
8814 return nullptr;
8815
8816 ValExpr = Val.get();
8817
8818 // OpenMP [2.7.1, Restrictions]
8819 // chunk_size must be a loop invariant integer expression with a positive
8820 // value.
8821 llvm::APSInt Result;
8822 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
8823 if (Result.isSigned() && !Result.isStrictlyPositive()) {
8824 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
8825 << "schedule" << 1 << ChunkSize->getSourceRange();
8826 return nullptr;
8827 }
8828 } else if (getOpenMPCaptureRegionForClause(
8829 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_schedule) !=
8830 OMPD_unknown &&
8831 !CurContext->isDependentContext()) {
8832 ValExpr = MakeFullExpr(ValExpr).get();
8833 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8834 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8835 HelperValStmt = buildPreInits(Context, Captures);
8836 }
8837 }
8838 }
8839
8840 return new (Context)
8841 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
8842 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
8843}
8844
8845OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
8846 SourceLocation StartLoc,
8847 SourceLocation EndLoc) {
8848 OMPClause *Res = nullptr;
8849 switch (Kind) {
8850 case OMPC_ordered:
8851 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
8852 break;
8853 case OMPC_nowait:
8854 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
8855 break;
8856 case OMPC_untied:
8857 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
8858 break;
8859 case OMPC_mergeable:
8860 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
8861 break;
8862 case OMPC_read:
8863 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
8864 break;
8865 case OMPC_write:
8866 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
8867 break;
8868 case OMPC_update:
8869 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
8870 break;
8871 case OMPC_capture:
8872 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
8873 break;
8874 case OMPC_seq_cst:
8875 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
8876 break;
8877 case OMPC_threads:
8878 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
8879 break;
8880 case OMPC_simd:
8881 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
8882 break;
8883 case OMPC_nogroup:
8884 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
8885 break;
8886 case OMPC_if:
8887 case OMPC_final:
8888 case OMPC_num_threads:
8889 case OMPC_safelen:
8890 case OMPC_simdlen:
8891 case OMPC_collapse:
8892 case OMPC_schedule:
8893 case OMPC_private:
8894 case OMPC_firstprivate:
8895 case OMPC_lastprivate:
8896 case OMPC_shared:
8897 case OMPC_reduction:
8898 case OMPC_task_reduction:
8899 case OMPC_in_reduction:
8900 case OMPC_linear:
8901 case OMPC_aligned:
8902 case OMPC_copyin:
8903 case OMPC_copyprivate:
8904 case OMPC_default:
8905 case OMPC_proc_bind:
8906 case OMPC_threadprivate:
8907 case OMPC_flush:
8908 case OMPC_depend:
8909 case OMPC_device:
8910 case OMPC_map:
8911 case OMPC_num_teams:
8912 case OMPC_thread_limit:
8913 case OMPC_priority:
8914 case OMPC_grainsize:
8915 case OMPC_num_tasks:
8916 case OMPC_hint:
8917 case OMPC_dist_schedule:
8918 case OMPC_defaultmap:
8919 case OMPC_unknown:
8920 case OMPC_uniform:
8921 case OMPC_to:
8922 case OMPC_from:
8923 case OMPC_use_device_ptr:
8924 case OMPC_is_device_ptr:
8925 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 8925)
;
8926 }
8927 return Res;
8928}
8929
8930OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
8931 SourceLocation EndLoc) {
8932 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setNowaitRegion();
8933 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
8934}
8935
8936OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
8937 SourceLocation EndLoc) {
8938 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
8939}
8940
8941OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
8942 SourceLocation EndLoc) {
8943 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
8944}
8945
8946OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
8947 SourceLocation EndLoc) {
8948 return new (Context) OMPReadClause(StartLoc, EndLoc);
8949}
8950
8951OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
8952 SourceLocation EndLoc) {
8953 return new (Context) OMPWriteClause(StartLoc, EndLoc);
8954}
8955
8956OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
8957 SourceLocation EndLoc) {
8958 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
8959}
8960
8961OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
8962 SourceLocation EndLoc) {
8963 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
8964}
8965
8966OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
8967 SourceLocation EndLoc) {
8968 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
8969}
8970
8971OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
8972 SourceLocation EndLoc) {
8973 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
8974}
8975
8976OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
8977 SourceLocation EndLoc) {
8978 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
8979}
8980
8981OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
8982 SourceLocation EndLoc) {
8983 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
8984}
8985
8986OMPClause *Sema::ActOnOpenMPVarListClause(
8987 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
8988 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
8989 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
8990 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
8991 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
8992 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
8993 SourceLocation DepLinMapLoc) {
8994 OMPClause *Res = nullptr;
8995 switch (Kind) {
8996 case OMPC_private:
8997 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8998 break;
8999 case OMPC_firstprivate:
9000 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9001 break;
9002 case OMPC_lastprivate:
9003 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9004 break;
9005 case OMPC_shared:
9006 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9007 break;
9008 case OMPC_reduction:
9009 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9010 EndLoc, ReductionIdScopeSpec, ReductionId);
9011 break;
9012 case OMPC_task_reduction:
9013 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9014 EndLoc, ReductionIdScopeSpec,
9015 ReductionId);
9016 break;
9017 case OMPC_in_reduction:
9018 Res =
9019 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9020 EndLoc, ReductionIdScopeSpec, ReductionId);
9021 break;
9022 case OMPC_linear:
9023 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9024 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9025 break;
9026 case OMPC_aligned:
9027 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9028 ColonLoc, EndLoc);
9029 break;
9030 case OMPC_copyin:
9031 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9032 break;
9033 case OMPC_copyprivate:
9034 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9035 break;
9036 case OMPC_flush:
9037 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9038 break;
9039 case OMPC_depend:
9040 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9041 StartLoc, LParenLoc, EndLoc);
9042 break;
9043 case OMPC_map:
9044 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
9045 DepLinMapLoc, ColonLoc, VarList, StartLoc,
9046 LParenLoc, EndLoc);
9047 break;
9048 case OMPC_to:
9049 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9050 break;
9051 case OMPC_from:
9052 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9053 break;
9054 case OMPC_use_device_ptr:
9055 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9056 break;
9057 case OMPC_is_device_ptr:
9058 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9059 break;
9060 case OMPC_if:
9061 case OMPC_final:
9062 case OMPC_num_threads:
9063 case OMPC_safelen:
9064 case OMPC_simdlen:
9065 case OMPC_collapse:
9066 case OMPC_default:
9067 case OMPC_proc_bind:
9068 case OMPC_schedule:
9069 case OMPC_ordered:
9070 case OMPC_nowait:
9071 case OMPC_untied:
9072 case OMPC_mergeable:
9073 case OMPC_threadprivate:
9074 case OMPC_read:
9075 case OMPC_write:
9076 case OMPC_update:
9077 case OMPC_capture:
9078 case OMPC_seq_cst:
9079 case OMPC_device:
9080 case OMPC_threads:
9081 case OMPC_simd:
9082 case OMPC_num_teams:
9083 case OMPC_thread_limit:
9084 case OMPC_priority:
9085 case OMPC_grainsize:
9086 case OMPC_nogroup:
9087 case OMPC_num_tasks:
9088 case OMPC_hint:
9089 case OMPC_dist_schedule:
9090 case OMPC_defaultmap:
9091 case OMPC_unknown:
9092 case OMPC_uniform:
9093 llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 9093)
;
9094 }
9095 return Res;
9096}
9097
9098ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
9099 ExprObjectKind OK, SourceLocation Loc) {
9100 ExprResult Res = BuildDeclRefExpr(
9101 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9102 if (!Res.isUsable())
9103 return ExprError();
9104 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9105 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9106 if (!Res.isUsable())
9107 return ExprError();
9108 }
9109 if (VK != VK_LValue && Res.get()->isGLValue()) {
9110 Res = DefaultLvalueConversion(Res.get());
9111 if (!Res.isUsable())
9112 return ExprError();
9113 }
9114 return Res;
9115}
9116
9117static std::pair<ValueDecl *, bool>
9118getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
9119 SourceRange &ERange, bool AllowArraySection = false) {
9120 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9121 RefExpr->containsUnexpandedParameterPack())
9122 return std::make_pair(nullptr, true);
9123
9124 // OpenMP [3.1, C/C++]
9125 // A list item is a variable name.
9126 // OpenMP [2.9.3.3, Restrictions, p.1]
9127 // A variable that is part of another variable (as an array or
9128 // structure element) cannot appear in a private clause.
9129 RefExpr = RefExpr->IgnoreParens();
9130 enum {
9131 NoArrayExpr = -1,
9132 ArraySubscript = 0,
9133 OMPArraySection = 1
9134 } IsArrayExpr = NoArrayExpr;
9135 if (AllowArraySection) {
9136 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9137 auto *Base = ASE->getBase()->IgnoreParenImpCasts();
9138 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9139 Base = TempASE->getBase()->IgnoreParenImpCasts();
9140 RefExpr = Base;
9141 IsArrayExpr = ArraySubscript;
9142 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9143 auto *Base = OASE->getBase()->IgnoreParenImpCasts();
9144 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9145 Base = TempOASE->getBase()->IgnoreParenImpCasts();
9146 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9147 Base = TempASE->getBase()->IgnoreParenImpCasts();
9148 RefExpr = Base;
9149 IsArrayExpr = OMPArraySection;
9150 }
9151 }
9152 ELoc = RefExpr->getExprLoc();
9153 ERange = RefExpr->getSourceRange();
9154 RefExpr = RefExpr->IgnoreParenImpCasts();
9155 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9156 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9157 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9158 (S.getCurrentThisType().isNull() || !ME ||
9159 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9160 !isa<FieldDecl>(ME->getMemberDecl()))) {
9161 if (IsArrayExpr != NoArrayExpr)
9162 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9163 << ERange;
9164 else {
9165 S.Diag(ELoc,
9166 AllowArraySection
9167 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9168 : diag::err_omp_expected_var_name_member_expr)
9169 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9170 }
9171 return std::make_pair(nullptr, false);
9172 }
9173 return std::make_pair(
9174 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9175}
9176
9177OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
9178 SourceLocation StartLoc,
9179 SourceLocation LParenLoc,
9180 SourceLocation EndLoc) {
9181 SmallVector<Expr *, 8> Vars;
9182 SmallVector<Expr *, 8> PrivateCopies;
9183 for (auto &RefExpr : VarList) {
9184 assert(RefExpr && "NULL expr in OpenMP private clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP private clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 9184, __extension__ __PRETTY_FUNCTION__))
;
9185 SourceLocation ELoc;
9186 SourceRange ERange;
9187 Expr *SimpleRefExpr = RefExpr;
9188 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9189 if (Res.second) {
9190 // It will be analyzed later.
9191 Vars.push_back(RefExpr);
9192 PrivateCopies.push_back(nullptr);
9193 }
9194 ValueDecl *D = Res.first;
9195 if (!D)
9196 continue;
9197
9198 QualType Type = D->getType();
9199 auto *VD = dyn_cast<VarDecl>(D);
9200
9201 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9202 // A variable that appears in a private clause must not have an incomplete
9203 // type or a reference type.
9204 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9205 continue;
9206 Type = Type.getNonReferenceType();
9207
9208 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9209 // in a Construct]
9210 // Variables with the predetermined data-sharing attributes may not be
9211 // listed in data-sharing attributes clauses, except for the cases
9212 // listed below. For these exceptions only, listing a predetermined
9213 // variable in a data-sharing attribute clause is allowed and overrides
9214 // the variable's predetermined data-sharing attributes.
9215 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
9216 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9217 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9218 << getOpenMPClauseName(OMPC_private);
9219 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9220 continue;
9221 }
9222
9223 auto CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
9224 // Variably modified types are not supported for tasks.
9225 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9226 isOpenMPTaskingDirective(CurrDir)) {
9227 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9228 << getOpenMPClauseName(OMPC_private) << Type
9229 << getOpenMPDirectiveName(CurrDir);
9230 bool IsDecl =
9231 !VD ||
9232 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9233 Diag(D->getLocation(),
9234 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9235 << D;
9236 continue;
9237 }
9238
9239 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9240 // A list item cannot appear in both a map clause and a data-sharing
9241 // attribute clause on the same construct
9242 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
9243 CurrDir == OMPD_target_teams ||
9244 CurrDir == OMPD_target_teams_distribute ||
9245 CurrDir == OMPD_target_teams_distribute_parallel_for ||
9246 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
9247 CurrDir == OMPD_target_teams_distribute_simd ||
9248 CurrDir == OMPD_target_parallel_for_simd ||
9249 CurrDir == OMPD_target_parallel_for) {
9250 OpenMPClauseKind ConflictKind;
9251 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
9252 VD, /*CurrentRegionOnly=*/true,
9253 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9254 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9255 ConflictKind = WhereFoundClauseKind;
9256 return true;
9257 })) {
9258 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9259 << getOpenMPClauseName(OMPC_private)
9260 << getOpenMPClauseName(ConflictKind)
9261 << getOpenMPDirectiveName(CurrDir);
9262 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9263 continue;
9264 }
9265 }
9266
9267 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9268 // A variable of class type (or array thereof) that appears in a private
9269 // clause requires an accessible, unambiguous default constructor for the
9270 // class type.
9271 // Generate helper private variable and initialize it with the default
9272 // value. The address of the original variable is replaced by the address of
9273 // the new private variable in CodeGen. This new variable is not added to
9274 // IdResolver, so the code in the OpenMP region uses original variable for
9275 // proper diagnostics.
9276 Type = Type.getUnqualifiedType();
9277 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9278 D->hasAttrs() ? &D->getAttrs() : nullptr);
9279 ActOnUninitializedDecl(VDPrivate);
9280 if (VDPrivate->isInvalidDecl())
9281 continue;
9282 auto VDPrivateRefExpr = buildDeclRefExpr(
9283 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9284
9285 DeclRefExpr *Ref = nullptr;
9286 if (!VD && !CurContext->isDependentContext())
9287 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9288 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9289 Vars.push_back((VD || CurContext->isDependentContext())
9290 ? RefExpr->IgnoreParens()
9291 : Ref);
9292 PrivateCopies.push_back(VDPrivateRefExpr);
9293 }
9294
9295 if (Vars.empty())
9296 return nullptr;
9297
9298 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9299 PrivateCopies);
9300}
9301
9302namespace {
9303class DiagsUninitializedSeveretyRAII {
9304private:
9305 DiagnosticsEngine &Diags;
9306 SourceLocation SavedLoc;
9307 bool IsIgnored;
9308
9309public:
9310 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9311 bool IsIgnored)
9312 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9313 if (!IsIgnored) {
9314 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9315 /*Map*/ diag::Severity::Ignored, Loc);
9316 }
9317 }
9318 ~DiagsUninitializedSeveretyRAII() {
9319 if (!IsIgnored)
9320 Diags.popMappings(SavedLoc);
9321 }
9322};
9323}
9324
9325OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
9326 SourceLocation StartLoc,
9327 SourceLocation LParenLoc,
9328 SourceLocation EndLoc) {
9329 SmallVector<Expr *, 8> Vars;
9330 SmallVector<Expr *, 8> PrivateCopies;
9331 SmallVector<Expr *, 8> Inits;
9332 SmallVector<Decl *, 4> ExprCaptures;
9333 bool IsImplicitClause =
9334 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9335 auto ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc();
9336
9337 for (auto &RefExpr : VarList) {
9338 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP firstprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 9338, __extension__ __PRETTY_FUNCTION__))
;
9339 SourceLocation ELoc;
9340 SourceRange ERange;
9341 Expr *SimpleRefExpr = RefExpr;
9342 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9343 if (Res.second) {
9344 // It will be analyzed later.
9345 Vars.push_back(RefExpr);
9346 PrivateCopies.push_back(nullptr);
9347 Inits.push_back(nullptr);
9348 }
9349 ValueDecl *D = Res.first;
9350 if (!D)
9351 continue;
9352
9353 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9354 QualType Type = D->getType();
9355 auto *VD = dyn_cast<VarDecl>(D);
9356
9357 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9358 // A variable that appears in a private clause must not have an incomplete
9359 // type or a reference type.
9360 if (RequireCompleteType(ELoc, Type,
9361 diag::err_omp_firstprivate_incomplete_type))
9362 continue;
9363 Type = Type.getNonReferenceType();
9364
9365 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9366 // A variable of class type (or array thereof) that appears in a private
9367 // clause requires an accessible, unambiguous copy constructor for the
9368 // class type.
9369 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9370
9371 // If an implicit firstprivate variable found it was checked already.
9372 DSAStackTy::DSAVarData TopDVar;
9373 if (!IsImplicitClause) {
9374 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
9375 TopDVar = DVar;
9376 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
9377 bool IsConstant = ElemType.isConstant(Context);
9378 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9379 // A list item that specifies a given variable may not appear in more
9380 // than one clause on the same directive, except that a variable may be
9381 // specified in both firstprivate and lastprivate clauses.
9382 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9383 // A list item may appear in a firstprivate or lastprivate clause but not
9384 // both.
9385 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9386 (isOpenMPDistributeDirective(CurrDir) ||
9387 DVar.CKind != OMPC_lastprivate) &&
9388 DVar.RefExpr) {
9389 Diag(ELoc, diag::err_omp_wrong_dsa)
9390 << getOpenMPClauseName(DVar.CKind)
9391 << getOpenMPClauseName(OMPC_firstprivate);
9392 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9393 continue;
9394 }
9395
9396 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9397 // in a Construct]
9398 // Variables with the predetermined data-sharing attributes may not be
9399 // listed in data-sharing attributes clauses, except for the cases
9400 // listed below. For these exceptions only, listing a predetermined
9401 // variable in a data-sharing attribute clause is allowed and overrides
9402 // the variable's predetermined data-sharing attributes.
9403 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9404 // in a Construct, C/C++, p.2]
9405 // Variables with const-qualified type having no mutable member may be
9406 // listed in a firstprivate clause, even if they are static data members.
9407 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9408 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9409 Diag(ELoc, diag::err_omp_wrong_dsa)
9410 << getOpenMPClauseName(DVar.CKind)
9411 << getOpenMPClauseName(OMPC_firstprivate);
9412 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9413 continue;
9414 }
9415
9416 // OpenMP [2.9.3.4, Restrictions, p.2]
9417 // A list item that is private within a parallel region must not appear
9418 // in a firstprivate clause on a worksharing construct if any of the
9419 // worksharing regions arising from the worksharing construct ever bind
9420 // to any of the parallel regions arising from the parallel construct.
9421 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9422 // A list item that is private within a teams region must not appear in a
9423 // firstprivate clause on a distribute construct if any of the distribute
9424 // regions arising from the distribute construct ever bind to any of the
9425 // teams regions arising from the teams construct.
9426 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9427 // A list item that appears in a reduction clause of a teams construct
9428 // must not appear in a firstprivate clause on a distribute construct if
9429 // any of the distribute regions arising from the distribute construct
9430 // ever bind to any of the teams regions arising from the teams construct.
9431 if ((isOpenMPWorksharingDirective(CurrDir) ||
9432 isOpenMPDistributeDirective(CurrDir)) &&
9433 !isOpenMPParallelDirective(CurrDir) &&
9434 !isOpenMPTeamsDirective(CurrDir)) {
9435 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
9436 if (DVar.CKind != OMPC_shared &&
9437 (isOpenMPParallelDirective(DVar.DKind) ||
9438 isOpenMPTeamsDirective(DVar.DKind) ||
9439 DVar.DKind == OMPD_unknown)) {
9440 Diag(ELoc, diag::err_omp_required_access)
9441 << getOpenMPClauseName(OMPC_firstprivate)
9442 << getOpenMPClauseName(OMPC_shared);
9443 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9444 continue;
9445 }
9446 }
9447 // OpenMP [2.9.3.4, Restrictions, p.3]
9448 // A list item that appears in a reduction clause of a parallel construct
9449 // must not appear in a firstprivate clause on a worksharing or task
9450 // construct if any of the worksharing or task regions arising from the
9451 // worksharing or task construct ever bind to any of the parallel regions
9452 // arising from the parallel construct.
9453 // OpenMP [2.9.3.4, Restrictions, p.4]
9454 // A list item that appears in a reduction clause in worksharing
9455 // construct must not appear in a firstprivate clause in a task construct
9456 // encountered during execution of any of the worksharing regions arising
9457 // from the worksharing construct.
9458 if (isOpenMPTaskingDirective(CurrDir)) {
9459 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnermostDSA(
9460 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
9461 [](OpenMPDirectiveKind K) -> bool {
9462 return isOpenMPParallelDirective(K) ||
9463 isOpenMPWorksharingDirective(K) ||
9464 isOpenMPTeamsDirective(K);
9465 },
9466 /*FromParent=*/true);
9467 if (DVar.CKind == OMPC_reduction &&
9468 (isOpenMPParallelDirective(DVar.DKind) ||
9469 isOpenMPWorksharingDirective(DVar.DKind) ||
9470 isOpenMPTeamsDirective(DVar.DKind))) {
9471 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9472 << getOpenMPDirectiveName(DVar.DKind);
9473 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9474 continue;
9475 }
9476 }
9477
9478 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9479 // A list item cannot appear in both a map clause and a data-sharing
9480 // attribute clause on the same construct
9481 if (isOpenMPTargetExecutionDirective(CurrDir)) {
9482 OpenMPClauseKind ConflictKind;
9483 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
9484 VD, /*CurrentRegionOnly=*/true,
9485 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9486 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9487 ConflictKind = WhereFoundClauseKind;
9488 return true;
9489 })) {
9490 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9491 << getOpenMPClauseName(OMPC_firstprivate)
9492 << getOpenMPClauseName(ConflictKind)
9493 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
9494 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9495 continue;
9496 }
9497 }
9498 }
9499
9500 // Variably modified types are not supported for tasks.
9501 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9502 isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
9503 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9504 << getOpenMPClauseName(OMPC_firstprivate) << Type
9505 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
9506 bool IsDecl =
9507 !VD ||
9508 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9509 Diag(D->getLocation(),
9510 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9511 << D;
9512 continue;
9513 }
9514
9515 Type = Type.getUnqualifiedType();
9516 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9517 D->hasAttrs() ? &D->getAttrs() : nullptr);
9518 // Generate helper private variable and initialize it with the value of the
9519 // original variable. The address of the original variable is replaced by
9520 // the address of the new private variable in the CodeGen. This new variable
9521 // is not added to IdResolver, so the code in the OpenMP region uses
9522 // original variable for proper diagnostics and variable capturing.
9523 Expr *VDInitRefExpr = nullptr;
9524 // For arrays generate initializer for single element and replace it by the
9525 // original array element in CodeGen.
9526 if (Type->isArrayType()) {
9527 auto VDInit =
9528 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9529 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9530 auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
9531 ElemType = ElemType.getUnqualifiedType();
9532 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9533 ".firstprivate.temp");
9534 InitializedEntity Entity =
9535 InitializedEntity::InitializeVariable(VDInitTemp);
9536 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
9537
9538 InitializationSequence InitSeq(*this, Entity, Kind, Init);
9539 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9540 if (Result.isInvalid())
9541 VDPrivate->setInvalidDecl();
9542 else
9543 VDPrivate->setInit(Result.getAs<Expr>());
9544 // Remove temp variable declaration.
9545 Context.Deallocate(VDInitTemp);
9546 } else {
9547 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9548 ".firstprivate.temp");
9549 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9550 RefExpr->getExprLoc());
9551 AddInitializerToDecl(VDPrivate,
9552 DefaultLvalueConversion(VDInitRefExpr).get(),
9553 /*DirectInit=*/false);
9554 }
9555 if (VDPrivate->isInvalidDecl()) {
9556 if (IsImplicitClause) {
9557 Diag(RefExpr->getExprLoc(),
9558 diag::note_omp_task_predetermined_firstprivate_here);
9559 }
9560 continue;
9561 }
9562 CurContext->addDecl(VDPrivate);
9563 auto VDPrivateRefExpr = buildDeclRefExpr(
9564 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9565 RefExpr->getExprLoc());
9566 DeclRefExpr *Ref = nullptr;
9567 if (!VD && !CurContext->isDependentContext()) {
9568 if (TopDVar.CKind == OMPC_lastprivate)
9569 Ref = TopDVar.PrivateCopy;
9570 else {
9571 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9572 if (!IsOpenMPCapturedDecl(D))
9573 ExprCaptures.push_back(Ref->getDecl());
9574 }
9575 }
9576 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9577 Vars.push_back((VD || CurContext->isDependentContext())
9578 ? RefExpr->IgnoreParens()
9579 : Ref);
9580 PrivateCopies.push_back(VDPrivateRefExpr);
9581 Inits.push_back(VDInitRefExpr);
9582 }
9583
9584 if (Vars.empty())
9585 return nullptr;
9586
9587 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9588 Vars, PrivateCopies, Inits,
9589 buildPreInits(Context, ExprCaptures));
9590}
9591
9592OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
9593 SourceLocation StartLoc,
9594 SourceLocation LParenLoc,
9595 SourceLocation EndLoc) {
9596 SmallVector<Expr *, 8> Vars;
9597 SmallVector<Expr *, 8> SrcExprs;
9598 SmallVector<Expr *, 8> DstExprs;
9599 SmallVector<Expr *, 8> AssignmentOps;
9600 SmallVector<Decl *, 4> ExprCaptures;
9601 SmallVector<Expr *, 4> ExprPostUpdates;
9602 for (auto &RefExpr : VarList) {
9603 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 9603, __extension__ __PRETTY_FUNCTION__))
;
9604 SourceLocation ELoc;
9605 SourceRange ERange;
9606 Expr *SimpleRefExpr = RefExpr;
9607 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9608 if (Res.second) {
9609 // It will be analyzed later.
9610 Vars.push_back(RefExpr);
9611 SrcExprs.push_back(nullptr);
9612 DstExprs.push_back(nullptr);
9613 AssignmentOps.push_back(nullptr);
9614 }
9615 ValueDecl *D = Res.first;
9616 if (!D)
9617 continue;
9618
9619 QualType Type = D->getType();
9620 auto *VD = dyn_cast<VarDecl>(D);
9621
9622 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9623 // A variable that appears in a lastprivate clause must not have an
9624 // incomplete type or a reference type.
9625 if (RequireCompleteType(ELoc, Type,
9626 diag::err_omp_lastprivate_incomplete_type))
9627 continue;
9628 Type = Type.getNonReferenceType();
9629
9630 OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
9631 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9632 // in a Construct]
9633 // Variables with the predetermined data-sharing attributes may not be
9634 // listed in data-sharing attributes clauses, except for the cases
9635 // listed below.
9636 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9637 // A list item may appear in a firstprivate or lastprivate clause but not
9638 // both.
9639 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
9640 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9641 (isOpenMPDistributeDirective(CurrDir) ||
9642 DVar.CKind != OMPC_firstprivate) &&
9643 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9644 Diag(ELoc, diag::err_omp_wrong_dsa)
9645 << getOpenMPClauseName(DVar.CKind)
9646 << getOpenMPClauseName(OMPC_lastprivate);
9647 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9648 continue;
9649 }
9650
9651 // OpenMP [2.14.3.5, Restrictions, p.2]
9652 // A list item that is private within a parallel region, or that appears in
9653 // the reduction clause of a parallel construct, must not appear in a
9654 // lastprivate clause on a worksharing construct if any of the corresponding
9655 // worksharing regions ever binds to any of the corresponding parallel
9656 // regions.
9657 DSAStackTy::DSAVarData TopDVar = DVar;
9658 if (isOpenMPWorksharingDirective(CurrDir) &&
9659 !isOpenMPParallelDirective(CurrDir) &&
9660 !isOpenMPTeamsDirective(CurrDir)) {
9661 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, true);
9662 if (DVar.CKind != OMPC_shared) {
9663 Diag(ELoc, diag::err_omp_required_access)
9664 << getOpenMPClauseName(OMPC_lastprivate)
9665 << getOpenMPClauseName(OMPC_shared);
9666 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9667 continue;
9668 }
9669 }
9670
9671 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9672 // A variable of class type (or array thereof) that appears in a
9673 // lastprivate clause requires an accessible, unambiguous default
9674 // constructor for the class type, unless the list item is also specified
9675 // in a firstprivate clause.
9676 // A variable of class type (or array thereof) that appears in a
9677 // lastprivate clause requires an accessible, unambiguous copy assignment
9678 // operator for the class type.
9679 Type = Context.getBaseElementType(Type).getNonReferenceType();
9680 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9681 Type.getUnqualifiedType(), ".lastprivate.src",
9682 D->hasAttrs() ? &D->getAttrs() : nullptr);
9683 auto *PseudoSrcExpr =
9684 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9685 auto *DstVD =
9686 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9687 D->hasAttrs() ? &D->getAttrs() : nullptr);
9688 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9689 // For arrays generate assignment operation for single element and replace
9690 // it by the original array element in CodeGen.
9691 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9692 PseudoDstExpr, PseudoSrcExpr);
9693 if (AssignmentOp.isInvalid())
9694 continue;
9695 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9696 /*DiscardedValue=*/true);
9697 if (AssignmentOp.isInvalid())
9698 continue;
9699
9700 DeclRefExpr *Ref = nullptr;
9701 if (!VD && !CurContext->isDependentContext()) {
9702 if (TopDVar.CKind == OMPC_firstprivate)
9703 Ref = TopDVar.PrivateCopy;
9704 else {
9705 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9706 if (!IsOpenMPCapturedDecl(D))
9707 ExprCaptures.push_back(Ref->getDecl());
9708 }
9709 if (TopDVar.CKind == OMPC_firstprivate ||
9710 (!IsOpenMPCapturedDecl(D) &&
9711 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9712 ExprResult RefRes = DefaultLvalueConversion(Ref);
9713 if (!RefRes.isUsable())
9714 continue;
9715 ExprResult PostUpdateRes =
9716 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9717 RefRes.get());
9718 if (!PostUpdateRes.isUsable())
9719 continue;
9720 ExprPostUpdates.push_back(
9721 IgnoredValueConversions(PostUpdateRes.get()).get());
9722 }
9723 }
9724 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9725 Vars.push_back((VD || CurContext->isDependentContext())
9726 ? RefExpr->IgnoreParens()
9727 : Ref);
9728 SrcExprs.push_back(PseudoSrcExpr);
9729 DstExprs.push_back(PseudoDstExpr);
9730 AssignmentOps.push_back(AssignmentOp.get());
9731 }
9732
9733 if (Vars.empty())
9734 return nullptr;
9735
9736 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9737 Vars, SrcExprs, DstExprs, AssignmentOps,
9738 buildPreInits(Context, ExprCaptures),
9739 buildPostUpdate(*this, ExprPostUpdates));
9740}
9741
9742OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
9743 SourceLocation StartLoc,
9744 SourceLocation LParenLoc,
9745 SourceLocation EndLoc) {
9746 SmallVector<Expr *, 8> Vars;
9747 for (auto &RefExpr : VarList) {
9748 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP lastprivate clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 9748, __extension__ __PRETTY_FUNCTION__))
;
9749 SourceLocation ELoc;
9750 SourceRange ERange;
9751 Expr *SimpleRefExpr = RefExpr;
9752 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9753 if (Res.second) {
9754 // It will be analyzed later.
9755 Vars.push_back(RefExpr);
9756 }
9757 ValueDecl *D = Res.first;
9758 if (!D)
9759 continue;
9760
9761 auto *VD = dyn_cast<VarDecl>(D);
9762 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9763 // in a Construct]
9764 // Variables with the predetermined data-sharing attributes may not be
9765 // listed in data-sharing attributes clauses, except for the cases
9766 // listed below. For these exceptions only, listing a predetermined
9767 // variable in a data-sharing attribute clause is allowed and overrides
9768 // the variable's predetermined data-sharing attributes.
9769 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
9770 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9771 DVar.RefExpr) {
9772 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9773 << getOpenMPClauseName(OMPC_shared);
9774 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
9775 continue;
9776 }
9777
9778 DeclRefExpr *Ref = nullptr;
9779 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9780 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9781 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9782 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9783 ? RefExpr->IgnoreParens()
9784 : Ref);
9785 }
9786
9787 if (Vars.empty())
9788 return nullptr;
9789
9790 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9791}
9792
9793namespace {
9794class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9795 DSAStackTy *Stack;
9796
9797public:
9798 bool VisitDeclRefExpr(DeclRefExpr *E) {
9799 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
9800 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
9801 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
9802 return false;
9803 if (DVar.CKind != OMPC_unknown)
9804 return true;
9805 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
9806 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
9807 /*FromParent=*/true);
9808 if (DVarPrivate.CKind != OMPC_unknown)
9809 return true;
9810 return false;
9811 }
9812 return false;
9813 }
9814 bool VisitStmt(Stmt *S) {
9815 for (auto Child : S->children()) {
9816 if (Child && Visit(Child))
9817 return true;
9818 }
9819 return false;
9820 }
9821 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
9822};
9823} // namespace
9824
9825namespace {
9826// Transform MemberExpression for specified FieldDecl of current class to
9827// DeclRefExpr to specified OMPCapturedExprDecl.
9828class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
9829 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
9830 ValueDecl *Field;
9831 DeclRefExpr *CapturedExpr;
9832
9833public:
9834 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
9835 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
9836
9837 ExprResult TransformMemberExpr(MemberExpr *E) {
9838 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
9839 E->getMemberDecl() == Field) {
9840 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
9841 return CapturedExpr;
9842 }
9843 return BaseTransform::TransformMemberExpr(E);
9844 }
9845 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
9846};
9847} // namespace
9848
9849template <typename T>
9850static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups,
9851 const llvm::function_ref<T(ValueDecl *)> &Gen) {
9852 for (auto &Set : Lookups) {
9853 for (auto *D : Set) {
9854 if (auto Res = Gen(cast<ValueDecl>(D)))
9855 return Res;
9856 }
9857 }
9858 return T();
9859}
9860
9861static ExprResult
9862buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
9863 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
9864 const DeclarationNameInfo &ReductionId, QualType Ty,
9865 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
9866 if (ReductionIdScopeSpec.isInvalid())
9867 return ExprError();
9868 SmallVector<UnresolvedSet<8>, 4> Lookups;
9869 if (S) {
9870 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
9871 Lookup.suppressDiagnostics();
9872 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
9873 auto *D = Lookup.getRepresentativeDecl();
9874 do {
9875 S = S->getParent();
9876 } while (S && !S->isDeclScope(D));
9877 if (S)
9878 S = S->getParent();
9879 Lookups.push_back(UnresolvedSet<8>());
9880 Lookups.back().append(Lookup.begin(), Lookup.end());
9881 Lookup.clear();
9882 }
9883 } else if (auto *ULE =
9884 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
9885 Lookups.push_back(UnresolvedSet<8>());
9886 Decl *PrevD = nullptr;
9887 for (auto *D : ULE->decls()) {
9888 if (D == PrevD)
9889 Lookups.push_back(UnresolvedSet<8>());
9890 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
9891 Lookups.back().addDecl(DRD);
9892 PrevD = D;
9893 }
9894 }
9895 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
9896 Ty->isInstantiationDependentType() ||
9897 Ty->containsUnexpandedParameterPack() ||
9898 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
9899 return !D->isInvalidDecl() &&
9900 (D->getType()->isDependentType() ||
9901 D->getType()->isInstantiationDependentType() ||
9902 D->getType()->containsUnexpandedParameterPack());
9903 })) {
9904 UnresolvedSet<8> ResSet;
9905 for (auto &Set : Lookups) {
9906 ResSet.append(Set.begin(), Set.end());
9907 // The last item marks the end of all declarations at the specified scope.
9908 ResSet.addDecl(Set[Set.size() - 1]);
9909 }
9910 return UnresolvedLookupExpr::Create(
9911 SemaRef.Context, /*NamingClass=*/nullptr,
9912 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
9913 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
9914 }
9915 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9916 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
9917 if (!D->isInvalidDecl() &&
9918 SemaRef.Context.hasSameType(D->getType(), Ty))
9919 return D;
9920 return nullptr;
9921 }))
9922 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9923 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9924 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
9925 if (!D->isInvalidDecl() &&
9926 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
9927 !Ty.isMoreQualifiedThan(D->getType()))
9928 return D;
9929 return nullptr;
9930 })) {
9931 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
9932 /*DetectVirtual=*/false);
9933 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
9934 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
9935 VD->getType().getUnqualifiedType()))) {
9936 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
9937 /*DiagID=*/0) !=
9938 Sema::AR_inaccessible) {
9939 SemaRef.BuildBasePathArray(Paths, BasePath);
9940 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9941 }
9942 }
9943 }
9944 }
9945 if (ReductionIdScopeSpec.isSet()) {
9946 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
9947 return ExprError();
9948 }
9949 return ExprEmpty();
9950}
9951
9952namespace {
9953/// Data for the reduction-based clauses.
9954struct ReductionData {
9955 /// List of original reduction items.
9956 SmallVector<Expr *, 8> Vars;
9957 /// List of private copies of the reduction items.
9958 SmallVector<Expr *, 8> Privates;
9959 /// LHS expressions for the reduction_op expressions.
9960 SmallVector<Expr *, 8> LHSs;
9961 /// RHS expressions for the reduction_op expressions.
9962 SmallVector<Expr *, 8> RHSs;
9963 /// Reduction operation expression.
9964 SmallVector<Expr *, 8> ReductionOps;
9965 /// Taskgroup descriptors for the corresponding reduction items in
9966 /// in_reduction clauses.
9967 SmallVector<Expr *, 8> TaskgroupDescriptors;
9968 /// List of captures for clause.
9969 SmallVector<Decl *, 4> ExprCaptures;
9970 /// List of postupdate expressions.
9971 SmallVector<Expr *, 4> ExprPostUpdates;
9972 ReductionData() = delete;
9973 /// Reserves required memory for the reduction data.
9974 ReductionData(unsigned Size) {
9975 Vars.reserve(Size);
9976 Privates.reserve(Size);
9977 LHSs.reserve(Size);
9978 RHSs.reserve(Size);
9979 ReductionOps.reserve(Size);
9980 TaskgroupDescriptors.reserve(Size);
9981 ExprCaptures.reserve(Size);
9982 ExprPostUpdates.reserve(Size);
9983 }
9984 /// Stores reduction item and reduction operation only (required for dependent
9985 /// reduction item).
9986 void push(Expr *Item, Expr *ReductionOp) {
9987 Vars.emplace_back(Item);
9988 Privates.emplace_back(nullptr);
9989 LHSs.emplace_back(nullptr);
9990 RHSs.emplace_back(nullptr);
9991 ReductionOps.emplace_back(ReductionOp);
9992 TaskgroupDescriptors.emplace_back(nullptr);
9993 }
9994 /// Stores reduction data.
9995 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
9996 Expr *TaskgroupDescriptor) {
9997 Vars.emplace_back(Item);
9998 Privates.emplace_back(Private);
9999 LHSs.emplace_back(LHS);
10000 RHSs.emplace_back(RHS);
10001 ReductionOps.emplace_back(ReductionOp);
10002 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10003 }
10004};
10005} // namespace
10006
10007static bool CheckOMPArraySectionConstantForReduction(
10008 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10009 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10010 const Expr *Length = OASE->getLength();
10011 if (Length == nullptr) {
10012 // For array sections of the form [1:] or [:], we would need to analyze
10013 // the lower bound...
10014 if (OASE->getColonLoc().isValid())
10015 return false;
10016
10017 // This is an array subscript which has implicit length 1!
10018 SingleElement = true;
10019 ArraySizes.push_back(llvm::APSInt::get(1));
10020 } else {
10021 llvm::APSInt ConstantLengthValue;
10022 if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
10023 return false;
10024
10025 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10026 ArraySizes.push_back(ConstantLengthValue);
10027 }
10028
10029 // Get the base of this array section and walk up from there.
10030 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10031
10032 // We require length = 1 for all array sections except the right-most to
10033 // guarantee that the memory region is contiguous and has no holes in it.
10034 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10035 Length = TempOASE->getLength();
10036 if (Length == nullptr) {
10037 // For array sections of the form [1:] or [:], we would need to analyze
10038 // the lower bound...
10039 if (OASE->getColonLoc().isValid())
10040 return false;
10041
10042 // This is an array subscript which has implicit length 1!
10043 ArraySizes.push_back(llvm::APSInt::get(1));
10044 } else {
10045 llvm::APSInt ConstantLengthValue;
10046 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
10047 ConstantLengthValue.getSExtValue() != 1)
10048 return false;
10049
10050 ArraySizes.push_back(ConstantLengthValue);
10051 }
10052 Base = TempOASE->getBase()->IgnoreParenImpCasts();
10053 }
10054
10055 // If we have a single element, we don't need to add the implicit lengths.
10056 if (!SingleElement) {
10057 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10058 // Has implicit length 1!
10059 ArraySizes.push_back(llvm::APSInt::get(1));
10060 Base = TempASE->getBase()->IgnoreParenImpCasts();
10061 }
10062 }
10063
10064 // This array section can be privatized as a single value or as a constant
10065 // sized array.
10066 return true;
10067}
10068
10069static bool ActOnOMPReductionKindClause(
10070 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10071 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10072 SourceLocation ColonLoc, SourceLocation EndLoc,
10073 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10074 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10075 auto DN = ReductionId.getName();
10076 auto OOK = DN.getCXXOverloadedOperator();
10077 BinaryOperatorKind BOK = BO_Comma;
10078
10079 ASTContext &Context = S.Context;
10080 // OpenMP [2.14.3.6, reduction clause]
10081 // C
10082 // reduction-identifier is either an identifier or one of the following
10083 // operators: +, -, *, &, |, ^, && and ||
10084 // C++
10085 // reduction-identifier is either an id-expression or one of the following
10086 // operators: +, -, *, &, |, ^, && and ||
10087 switch (OOK) {
1
Control jumps to 'case OO_None:' at line 10149
10088 case OO_Plus:
10089 case OO_Minus:
10090 BOK = BO_Add;
10091 break;
10092 case OO_Star:
10093 BOK = BO_Mul;
10094 break;
10095 case OO_Amp:
10096 BOK = BO_And;
10097 break;
10098 case OO_Pipe:
10099 BOK = BO_Or;
10100 break;
10101 case OO_Caret:
10102 BOK = BO_Xor;
10103 break;
10104 case OO_AmpAmp:
10105 BOK = BO_LAnd;
10106 break;
10107 case OO_PipePipe:
10108 BOK = BO_LOr;
10109 break;
10110 case OO_New:
10111 case OO_Delete:
10112 case OO_Array_New:
10113 case OO_Array_Delete:
10114 case OO_Slash:
10115 case OO_Percent:
10116 case OO_Tilde:
10117 case OO_Exclaim:
10118 case OO_Equal:
10119 case OO_Less:
10120 case OO_Greater:
10121 case OO_LessEqual:
10122 case OO_GreaterEqual:
10123 case OO_PlusEqual:
10124 case OO_MinusEqual:
10125 case OO_StarEqual:
10126 case OO_SlashEqual:
10127 case OO_PercentEqual:
10128 case OO_CaretEqual:
10129 case OO_AmpEqual:
10130 case OO_PipeEqual:
10131 case OO_LessLess:
10132 case OO_GreaterGreater:
10133 case OO_LessLessEqual:
10134 case OO_GreaterGreaterEqual:
10135 case OO_EqualEqual:
10136 case OO_ExclaimEqual:
10137 case OO_Spaceship:
10138 case OO_PlusPlus:
10139 case OO_MinusMinus:
10140 case OO_Comma:
10141 case OO_ArrowStar:
10142 case OO_Arrow:
10143 case OO_Call:
10144 case OO_Subscript:
10145 case OO_Conditional:
10146 case OO_Coawait:
10147 case NUM_OVERLOADED_OPERATORS:
10148 llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 10148)
;
10149 case OO_None:
10150 if (auto *II = DN.getAsIdentifierInfo()) {
2
Taking false branch
10151 if (II->isStr("max"))
10152 BOK = BO_GT;
10153 else if (II->isStr("min"))
10154 BOK = BO_LT;
10155 }
10156 break;
3
Execution continues on line 10158
10157 }
10158 SourceRange ReductionIdRange;
10159 if (ReductionIdScopeSpec.isValid())
4
Taking false branch
10160 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10161 else
10162 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10163 ReductionIdRange.setEnd(ReductionId.getEndLoc());
10164
10165 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10166 bool FirstIter = true;
10167 for (auto RefExpr : VarList) {
5
Assuming '__begin1' is not equal to '__end1'
10168 assert(RefExpr && "nullptr expr in OpenMP reduction clause.")(static_cast <bool> (RefExpr && "nullptr expr in OpenMP reduction clause."
) ? void (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 10168, __extension__ __PRETTY_FUNCTION__))
;
10169 // OpenMP [2.1, C/C++]
10170 // A list item is a variable or array section, subject to the restrictions
10171 // specified in Section 2.4 on page 42 and in each of the sections
10172 // describing clauses and directives for which a list appears.
10173 // OpenMP [2.14.3.3, Restrictions, p.1]
10174 // A variable that is part of another variable (as an array or
10175 // structure element) cannot appear in a private clause.
10176 if (!FirstIter && IR != ER)
10177 ++IR;
10178 FirstIter = false;
10179 SourceLocation ELoc;
10180 SourceRange ERange;
10181 Expr *SimpleRefExpr = RefExpr;
10182 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10183 /*AllowArraySection=*/true);
10184 if (Res.second) {
6
Taking false branch
10185 // Try to find 'declare reduction' corresponding construct before using
10186 // builtin/overloaded operators.
10187 QualType Type = Context.DependentTy;
10188 CXXCastPath BasePath;
10189 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10190 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10191 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10192 Expr *ReductionOp = nullptr;
10193 if (S.CurContext->isDependentContext() &&
10194 (DeclareReductionRef.isUnset() ||
10195 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10196 ReductionOp = DeclareReductionRef.get();
10197 // It will be analyzed later.
10198 RD.push(RefExpr, ReductionOp);
10199 }
10200 ValueDecl *D = Res.first;
10201 if (!D)
7
Assuming 'D' is non-null
8
Taking false branch
10202 continue;
10203
10204 Expr *TaskgroupDescriptor = nullptr;
10205 QualType Type;
10206 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10207 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10208 if (ASE)
9
Taking false branch
10209 Type = ASE->getType().getNonReferenceType();
10210 else if (OASE) {
10
Taking false branch
10211 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10212 if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
10213 Type = ATy->getElementType();
10214 else
10215 Type = BaseType->getPointeeType();
10216 Type = Type.getNonReferenceType();
10217 } else
10218 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10219 auto *VD = dyn_cast<VarDecl>(D);
10220
10221 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10222 // A variable that appears in a private clause must not have an incomplete
10223 // type or a reference type.
10224 if (S.RequireCompleteType(ELoc, Type,
11
Assuming the condition is false
12
Taking false branch
10225 diag::err_omp_reduction_incomplete_type))
10226 continue;
10227 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10228 // A list item that appears in a reduction clause must not be
10229 // const-qualified.
10230 if (Type.getNonReferenceType().isConstant(Context)) {
13
Assuming the condition is false
14
Taking false branch
10231 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10232 if (!ASE && !OASE) {
10233 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10234 VarDecl::DeclarationOnly;
10235 S.Diag(D->getLocation(),
10236 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10237 << D;
10238 }
10239 continue;
10240 }
10241 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10242 // If a list-item is a reference type then it must bind to the same object
10243 // for all threads of the team.
10244 if (!ASE && !OASE && VD) {
15
Taking false branch
10245 VarDecl *VDDef = VD->getDefinition();
10246 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10247 DSARefChecker Check(Stack);
10248 if (Check.Visit(VDDef->getInit())) {
10249 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10250 << getOpenMPClauseName(ClauseKind) << ERange;
10251 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10252 continue;
10253 }
10254 }
10255 }
10256
10257 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10258 // in a Construct]
10259 // Variables with the predetermined data-sharing attributes may not be
10260 // listed in data-sharing attributes clauses, except for the cases
10261 // listed below. For these exceptions only, listing a predetermined
10262 // variable in a data-sharing attribute clause is allowed and overrides
10263 // the variable's predetermined data-sharing attributes.
10264 // OpenMP [2.14.3.6, Restrictions, p.3]
10265 // Any number of reduction clauses can be specified on the directive,
10266 // but a list item can appear only once in the reduction clauses for that
10267 // directive.
10268 DSAStackTy::DSAVarData DVar;
10269 DVar = Stack->getTopDSA(D, false);
10270 if (DVar.CKind == OMPC_reduction) {
16
Taking false branch
10271 S.Diag(ELoc, diag::err_omp_once_referenced)
10272 << getOpenMPClauseName(ClauseKind);
10273 if (DVar.RefExpr)
10274 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10275 continue;
10276 } else if (DVar.CKind != OMPC_unknown) {
17
Taking false branch
10277 S.Diag(ELoc, diag::err_omp_wrong_dsa)
10278 << getOpenMPClauseName(DVar.CKind)
10279 << getOpenMPClauseName(OMPC_reduction);
10280 ReportOriginalDSA(S, Stack, D, DVar);
10281 continue;
10282 }
10283
10284 // OpenMP [2.14.3.6, Restrictions, p.1]
10285 // A list item that appears in a reduction clause of a worksharing
10286 // construct must be shared in the parallel regions to which any of the
10287 // worksharing regions arising from the worksharing construct bind.
10288 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10289 if (isOpenMPWorksharingDirective(CurrDir) &&
18
Assuming the condition is false
10290 !isOpenMPParallelDirective(CurrDir) &&
10291 !isOpenMPTeamsDirective(CurrDir)) {
10292 DVar = Stack->getImplicitDSA(D, true);
10293 if (DVar.CKind != OMPC_shared) {
10294 S.Diag(ELoc, diag::err_omp_required_access)
10295 << getOpenMPClauseName(OMPC_reduction)
10296 << getOpenMPClauseName(OMPC_shared);
10297 ReportOriginalDSA(S, Stack, D, DVar);
10298 continue;
10299 }
10300 }
10301
10302 // Try to find 'declare reduction' corresponding construct before using
10303 // builtin/overloaded operators.
10304 CXXCastPath BasePath;
10305 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10306 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10307 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19
Assuming 'IR' is not equal to 'ER'
20
'?' condition is false
10308 if (DeclareReductionRef.isInvalid())
21
Assuming the condition is false
22
Taking false branch
10309 continue;
10310 if (S.CurContext->isDependentContext() &&
23
Assuming the condition is false
24
Taking false branch
10311 (DeclareReductionRef.isUnset() ||
10312 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10313 RD.push(RefExpr, DeclareReductionRef.get());
10314 continue;
10315 }
10316 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
25
Taking false branch
10317 // Not allowed reduction identifier is found.
10318 S.Diag(ReductionId.getLocStart(),
10319 diag::err_omp_unknown_reduction_identifier)
10320 << Type << ReductionIdRange;
10321 continue;
10322 }
10323
10324 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10325 // The type of a list item that appears in a reduction clause must be valid
10326 // for the reduction-identifier. For a max or min reduction in C, the type
10327 // of the list item must be an allowed arithmetic data type: char, int,
10328 // float, double, or _Bool, possibly modified with long, short, signed, or
10329 // unsigned. For a max or min reduction in C++, the type of the list item
10330 // must be an allowed arithmetic data type: char, wchar_t, int, float,
10331 // double, or bool, possibly modified with long, short, signed, or unsigned.
10332 if (DeclareReductionRef.isUnset()) {
26
Taking false branch
10333 if ((BOK == BO_GT || BOK == BO_LT) &&
10334 !(Type->isScalarType() ||
10335 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10336 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10337 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10338 if (!ASE && !OASE) {
10339 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10340 VarDecl::DeclarationOnly;
10341 S.Diag(D->getLocation(),
10342 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10343 << D;
10344 }
10345 continue;
10346 }
10347 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10348 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10349 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10350 << getOpenMPClauseName(ClauseKind);
10351 if (!ASE && !OASE) {
10352 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10353 VarDecl::DeclarationOnly;
10354 S.Diag(D->getLocation(),
10355 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10356 << D;
10357 }
10358 continue;
10359 }
10360 }
10361
10362 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10363 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10364 D->hasAttrs() ? &D->getAttrs() : nullptr);
27
Assuming the condition is false
28
'?' condition is false
10365 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10366 D->hasAttrs() ? &D->getAttrs() : nullptr);
29
'?' condition is false
10367 auto PrivateTy = Type;
10368
10369 // Try if we can determine constant lengths for all array sections and avoid
10370 // the VLA.
10371 bool ConstantLengthOASE = false;
10372 if (OASE) {
30
Taking false branch
10373 bool SingleElement;
10374 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
10375 ConstantLengthOASE = CheckOMPArraySectionConstantForReduction(
10376 Context, OASE, SingleElement, ArraySizes);
10377
10378 // If we don't have a single element, we must emit a constant array type.
10379 if (ConstantLengthOASE && !SingleElement) {
10380 for (auto &Size : ArraySizes) {
10381 PrivateTy = Context.getConstantArrayType(
10382 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10383 }
10384 }
10385 }
10386
10387 if ((OASE && !ConstantLengthOASE) ||
31
Taking true branch
10388 (!OASE && !ASE &&
10389 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
10390 if (!Context.getTargetInfo().isVLASupported() &&
32
Assuming the condition is false
10391 S.shouldDiagnoseTargetSupportFromOpenMP()) {
10392 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10393 S.Diag(ELoc, diag::note_vla_unsupported);
10394 continue;
10395 }
10396 // For arrays/array sections only:
10397 // Create pseudo array type for private copy. The size for this array will
10398 // be generated during codegen.
10399 // For array subscripts or single variables Private Ty is the same as Type
10400 // (type of the variable or single array element).
10401 PrivateTy = Context.getVariableArrayType(
10402 Type,
10403 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10404 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10405 } else if (!ASE && !OASE &&
10406 Context.getAsArrayType(D->getType().getNonReferenceType()))
10407 PrivateTy = D->getType().getNonReferenceType();
10408 // Private copy.
10409 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10410 D->hasAttrs() ? &D->getAttrs() : nullptr);
33
'?' condition is false
10411 // Add initializer for private variable.
10412 Expr *Init = nullptr;
10413 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10414 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10415 if (DeclareReductionRef.isUsable()) {
34
Taking true branch
10416 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10417 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10418 if (DRD->getInitializer()) {
35
Assuming the condition is false
36
Taking false branch
10419 Init = DRDRef;
10420 RHSVD->setInit(DRDRef);
10421 RHSVD->setInitStyle(VarDecl::CallInit);
10422 }
10423 } else {
10424 switch (BOK) {
10425 case BO_Add:
10426 case BO_Xor:
10427 case BO_Or:
10428 case BO_LOr:
10429 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10430 if (Type->isScalarType() || Type->isAnyComplexType())
10431 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10432 break;
10433 case BO_Mul:
10434 case BO_LAnd:
10435 if (Type->isScalarType() || Type->isAnyComplexType()) {
10436 // '*' and '&&' reduction ops - initializer is '1'.
10437 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10438 }
10439 break;
10440 case BO_And: {
10441 // '&' reduction op - initializer is '~0'.
10442 QualType OrigType = Type;
10443 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10444 Type = ComplexTy->getElementType();
10445 if (Type->isRealFloatingType()) {
10446 llvm::APFloat InitValue =
10447 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10448 /*isIEEE=*/true);
10449 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10450 Type, ELoc);
10451 } else if (Type->isScalarType()) {
10452 auto Size = Context.getTypeSize(Type);
10453 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10454 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10455 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10456 }
10457 if (Init && OrigType->isAnyComplexType()) {
10458 // Init = 0xFFFF + 0xFFFFi;
10459 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10460 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10461 }
10462 Type = OrigType;
10463 break;
10464 }
10465 case BO_LT:
10466 case BO_GT: {
10467 // 'min' reduction op - initializer is 'Largest representable number in
10468 // the reduction list item type'.
10469 // 'max' reduction op - initializer is 'Least representable number in
10470 // the reduction list item type'.
10471 if (Type->isIntegerType() || Type->isPointerType()) {
10472 bool IsSigned = Type->hasSignedIntegerRepresentation();
10473 auto Size = Context.getTypeSize(Type);
10474 QualType IntTy =
10475 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10476 llvm::APInt InitValue =
10477 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10478 : llvm::APInt::getMinValue(Size)
10479 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10480 : llvm::APInt::getMaxValue(Size);
10481 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10482 if (Type->isPointerType()) {
10483 // Cast to pointer type.
10484 auto CastExpr = S.BuildCStyleCastExpr(
10485 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10486 if (CastExpr.isInvalid())
10487 continue;
10488 Init = CastExpr.get();
10489 }
10490 } else if (Type->isRealFloatingType()) {
10491 llvm::APFloat InitValue = llvm::APFloat::getLargest(
10492 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10493 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10494 Type, ELoc);
10495 }
10496 break;
10497 }
10498 case BO_PtrMemD:
10499 case BO_PtrMemI:
10500 case BO_MulAssign:
10501 case BO_Div:
10502 case BO_Rem:
10503 case BO_Sub:
10504 case BO_Shl:
10505 case BO_Shr:
10506 case BO_LE:
10507 case BO_GE:
10508 case BO_EQ:
10509 case BO_NE:
10510 case BO_Cmp:
10511 case BO_AndAssign:
10512 case BO_XorAssign:
10513 case BO_OrAssign:
10514 case BO_Assign:
10515 case BO_AddAssign:
10516 case BO_SubAssign:
10517 case BO_DivAssign:
10518 case BO_RemAssign:
10519 case BO_ShlAssign:
10520 case BO_ShrAssign:
10521 case BO_Comma:
10522 llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 10522)
;
10523 }
10524 }
10525 if (Init && DeclareReductionRef.isUnset())
10526 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10527 else if (!Init)
37
Taking true branch
10528 S.ActOnUninitializedDecl(RHSVD);
10529 if (RHSVD->isInvalidDecl())
38
Assuming the condition is false
39
Taking false branch
10530 continue;
10531 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
40
Assuming the condition is false
10532 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10533 << Type << ReductionIdRange;
10534 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10535 VarDecl::DeclarationOnly;
10536 S.Diag(D->getLocation(),
10537 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10538 << D;
10539 continue;
10540 }
10541 // Store initializer for single element in private copy. Will be used during
10542 // codegen.
10543 PrivateVD->setInit(RHSVD->getInit());
10544 PrivateVD->setInitStyle(RHSVD->getInitStyle());
10545 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10546 ExprResult ReductionOp;
10547 if (DeclareReductionRef.isUsable()) {
41
Taking true branch
10548 QualType RedTy = DeclareReductionRef.get()->getType();
10549 QualType PtrRedTy = Context.getPointerType(RedTy);
10550 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10551 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10552 if (!BasePath.empty()) {
42
Taking false branch
10553 LHS = S.DefaultLvalueConversion(LHS.get());
10554 RHS = S.DefaultLvalueConversion(RHS.get());
10555 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10556 CK_UncheckedDerivedToBase, LHS.get(),
10557 &BasePath, LHS.get()->getValueKind());
10558 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10559 CK_UncheckedDerivedToBase, RHS.get(),
10560 &BasePath, RHS.get()->getValueKind());
10561 }
10562 FunctionProtoType::ExtProtoInfo EPI;
10563 QualType Params[] = {PtrRedTy, PtrRedTy};
10564 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10565 auto *OVE = new (Context) OpaqueValueExpr(
10566 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10567 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10568 Expr *Args[] = {LHS.get(), RHS.get()};
10569 ReductionOp = new (Context)
10570 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10571 } else {
10572 ReductionOp = S.BuildBinOp(
10573 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10574 if (ReductionOp.isUsable()) {
10575 if (BOK != BO_LT && BOK != BO_GT) {
10576 ReductionOp =
10577 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10578 BO_Assign, LHSDRE, ReductionOp.get());
10579 } else {
10580 auto *ConditionalOp = new (Context)
10581 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10582 Type, VK_LValue, OK_Ordinary);
10583 ReductionOp =
10584 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10585 BO_Assign, LHSDRE, ConditionalOp);
10586 }
10587 if (ReductionOp.isUsable())
10588 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10589 }
10590 if (!ReductionOp.isUsable())
10591 continue;
10592 }
10593
10594 // OpenMP [2.15.4.6, Restrictions, p.2]
10595 // A list item that appears in an in_reduction clause of a task construct
10596 // must appear in a task_reduction clause of a construct associated with a
10597 // taskgroup region that includes the participating task in its taskgroup
10598 // set. The construct associated with the innermost region that meets this
10599 // condition must specify the same reduction-identifier as the in_reduction
10600 // clause.
10601 if (ClauseKind == OMPC_in_reduction) {
43
Assuming 'ClauseKind' is not equal to OMPC_in_reduction
44
Taking false branch
10602 SourceRange ParentSR;
10603 BinaryOperatorKind ParentBOK;
10604 const Expr *ParentReductionOp;
10605 Expr *ParentBOKTD, *ParentReductionOpTD;
10606 DSAStackTy::DSAVarData ParentBOKDSA =
10607 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10608 ParentBOKTD);
10609 DSAStackTy::DSAVarData ParentReductionOpDSA =
10610 Stack->getTopMostTaskgroupReductionData(
10611 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10612 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10613 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10614 if (!IsParentBOK && !IsParentReductionOp) {
10615 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10616 continue;
10617 }
10618 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10619 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10620 IsParentReductionOp) {
10621 bool EmitError = true;
10622 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10623 llvm::FoldingSetNodeID RedId, ParentRedId;
10624 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10625 DeclareReductionRef.get()->Profile(RedId, Context,
10626 /*Canonical=*/true);
10627 EmitError = RedId != ParentRedId;
10628 }
10629 if (EmitError) {
10630 S.Diag(ReductionId.getLocStart(),
10631 diag::err_omp_reduction_identifier_mismatch)
10632 << ReductionIdRange << RefExpr->getSourceRange();
10633 S.Diag(ParentSR.getBegin(),
10634 diag::note_omp_previous_reduction_identifier)
10635 << ParentSR
10636 << (IsParentBOK ? ParentBOKDSA.RefExpr
10637 : ParentReductionOpDSA.RefExpr)
10638 ->getSourceRange();
10639 continue;
10640 }
10641 }
10642 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10643 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.")(static_cast <bool> (TaskgroupDescriptor && "Taskgroup descriptor must be defined."
) ? void (0) : __assert_fail ("TaskgroupDescriptor && \"Taskgroup descriptor must be defined.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 10643, __extension__ __PRETTY_FUNCTION__))
;
10644 }
10645
10646 DeclRefExpr *Ref = nullptr;
10647 Expr *VarsExpr = RefExpr->IgnoreParens();
10648 if (!VD && !S.CurContext->isDependentContext()) {
45
Assuming the condition is true
46
Taking true branch
10649 if (ASE || OASE) {
47
Taking false branch
10650 TransformExprToCaptures RebuildToCapture(S, D);
10651 VarsExpr =
10652 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10653 Ref = RebuildToCapture.getCapturedExpr();
10654 } else {
10655 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
48
Calling 'buildCapture'
10656 }
10657 if (!S.IsOpenMPCapturedDecl(D)) {
10658 RD.ExprCaptures.emplace_back(Ref->getDecl());
10659 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10660 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10661 if (!RefRes.isUsable())
10662 continue;
10663 ExprResult PostUpdateRes =
10664 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10665 RefRes.get());
10666 if (!PostUpdateRes.isUsable())
10667 continue;
10668 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10669 Stack->getCurrentDirective() == OMPD_taskgroup) {
10670 S.Diag(RefExpr->getExprLoc(),
10671 diag::err_omp_reduction_non_addressable_expression)
10672 << RefExpr->getSourceRange();
10673 continue;
10674 }
10675 RD.ExprPostUpdates.emplace_back(
10676 S.IgnoredValueConversions(PostUpdateRes.get()).get());
10677 }
10678 }
10679 }
10680 // All reduction items are still marked as reduction (to do not increase
10681 // code base size).
10682 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10683 if (CurrDir == OMPD_taskgroup) {
10684 if (DeclareReductionRef.isUsable())
10685 Stack->addTaskgroupReductionData(D, ReductionIdRange,
10686 DeclareReductionRef.get());
10687 else
10688 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10689 }
10690 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10691 TaskgroupDescriptor);
10692 }
10693 return RD.Vars.empty();
10694}
10695
10696OMPClause *Sema::ActOnOpenMPReductionClause(
10697 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10698 SourceLocation ColonLoc, SourceLocation EndLoc,
10699 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10700 ArrayRef<Expr *> UnresolvedReductions) {
10701 ReductionData RD(VarList.size());
10702
10703 if (ActOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_reduction, VarList,
10704 StartLoc, LParenLoc, ColonLoc, EndLoc,
10705 ReductionIdScopeSpec, ReductionId,
10706 UnresolvedReductions, RD))
10707 return nullptr;
10708
10709 return OMPReductionClause::Create(
10710 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10711 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10712 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10713 buildPreInits(Context, RD.ExprCaptures),
10714 buildPostUpdate(*this, RD.ExprPostUpdates));
10715}
10716
10717OMPClause *Sema::ActOnOpenMPTaskReductionClause(
10718 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10719 SourceLocation ColonLoc, SourceLocation EndLoc,
10720 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10721 ArrayRef<Expr *> UnresolvedReductions) {
10722 ReductionData RD(VarList.size());
10723
10724 if (ActOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_task_reduction,
10725 VarList, StartLoc, LParenLoc, ColonLoc,
10726 EndLoc, ReductionIdScopeSpec, ReductionId,
10727 UnresolvedReductions, RD))
10728 return nullptr;
10729
10730 return OMPTaskReductionClause::Create(
10731 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10732 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10733 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10734 buildPreInits(Context, RD.ExprCaptures),
10735 buildPostUpdate(*this, RD.ExprPostUpdates));
10736}
10737
10738OMPClause *Sema::ActOnOpenMPInReductionClause(
10739 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10740 SourceLocation ColonLoc, SourceLocation EndLoc,
10741 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10742 ArrayRef<Expr *> UnresolvedReductions) {
10743 ReductionData RD(VarList.size());
10744
10745 if (ActOnOMPReductionKindClause(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_in_reduction, VarList,
10746 StartLoc, LParenLoc, ColonLoc, EndLoc,
10747 ReductionIdScopeSpec, ReductionId,
10748 UnresolvedReductions, RD))
10749 return nullptr;
10750
10751 return OMPInReductionClause::Create(
10752 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10753 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10754 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10755 buildPreInits(Context, RD.ExprCaptures),
10756 buildPostUpdate(*this, RD.ExprPostUpdates));
10757}
10758
10759bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
10760 SourceLocation LinLoc) {
10761 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10762 LinKind == OMPC_LINEAR_unknown) {
10763 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10764 return true;
10765 }
10766 return false;
10767}
10768
10769bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc,
10770 OpenMPLinearClauseKind LinKind,
10771 QualType Type) {
10772 auto *VD = dyn_cast_or_null<VarDecl>(D);
10773 // A variable must not have an incomplete type or a reference type.
10774 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10775 return true;
10776 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10777 !Type->isReferenceType()) {
10778 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10779 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10780 return true;
10781 }
10782 Type = Type.getNonReferenceType();
10783
10784 // A list item must not be const-qualified.
10785 if (Type.isConstant(Context)) {
10786 Diag(ELoc, diag::err_omp_const_variable)
10787 << getOpenMPClauseName(OMPC_linear);
10788 if (D) {
10789 bool IsDecl =
10790 !VD ||
10791 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10792 Diag(D->getLocation(),
10793 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10794 << D;
10795 }
10796 return true;
10797 }
10798
10799 // A list item must be of integral or pointer type.
10800 Type = Type.getUnqualifiedType().getCanonicalType();
10801 const auto *Ty = Type.getTypePtrOrNull();
10802 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
10803 !Ty->isPointerType())) {
10804 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
10805 if (D) {
10806 bool IsDecl =
10807 !VD ||
10808 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10809 Diag(D->getLocation(),
10810 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10811 << D;
10812 }
10813 return true;
10814 }
10815 return false;
10816}
10817
10818OMPClause *Sema::ActOnOpenMPLinearClause(
10819 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
10820 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
10821 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
10822 SmallVector<Expr *, 8> Vars;
10823 SmallVector<Expr *, 8> Privates;
10824 SmallVector<Expr *, 8> Inits;
10825 SmallVector<Decl *, 4> ExprCaptures;
10826 SmallVector<Expr *, 4> ExprPostUpdates;
10827 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
10828 LinKind = OMPC_LINEAR_val;
10829 for (auto &RefExpr : VarList) {
10830 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 10830, __extension__ __PRETTY_FUNCTION__))
;
10831 SourceLocation ELoc;
10832 SourceRange ERange;
10833 Expr *SimpleRefExpr = RefExpr;
10834 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10835 /*AllowArraySection=*/false);
10836 if (Res.second) {
10837 // It will be analyzed later.
10838 Vars.push_back(RefExpr);
10839 Privates.push_back(nullptr);
10840 Inits.push_back(nullptr);
10841 }
10842 ValueDecl *D = Res.first;
10843 if (!D)
10844 continue;
10845
10846 QualType Type = D->getType();
10847 auto *VD = dyn_cast<VarDecl>(D);
10848
10849 // OpenMP [2.14.3.7, linear clause]
10850 // A list-item cannot appear in more than one linear clause.
10851 // A list-item that appears in a linear clause cannot appear in any
10852 // other data-sharing attribute clause.
10853 DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
10854 if (DVar.RefExpr) {
10855 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10856 << getOpenMPClauseName(OMPC_linear);
10857 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
10858 continue;
10859 }
10860
10861 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
10862 continue;
10863 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
10864
10865 // Build private copy of original var.
10866 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(),
10867 D->hasAttrs() ? &D->getAttrs() : nullptr);
10868 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
10869 // Build var to save initial value.
10870 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
10871 Expr *InitExpr;
10872 DeclRefExpr *Ref = nullptr;
10873 if (!VD && !CurContext->isDependentContext()) {
10874 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10875 if (!IsOpenMPCapturedDecl(D)) {
10876 ExprCaptures.push_back(Ref->getDecl());
10877 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10878 ExprResult RefRes = DefaultLvalueConversion(Ref);
10879 if (!RefRes.isUsable())
10880 continue;
10881 ExprResult PostUpdateRes =
10882 BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
10883 SimpleRefExpr, RefRes.get());
10884 if (!PostUpdateRes.isUsable())
10885 continue;
10886 ExprPostUpdates.push_back(
10887 IgnoredValueConversions(PostUpdateRes.get()).get());
10888 }
10889 }
10890 }
10891 if (LinKind == OMPC_LINEAR_uval)
10892 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
10893 else
10894 InitExpr = VD ? SimpleRefExpr : Ref;
10895 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
10896 /*DirectInit=*/false);
10897 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
10898
10899 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
10900 Vars.push_back((VD || CurContext->isDependentContext())
10901 ? RefExpr->IgnoreParens()
10902 : Ref);
10903 Privates.push_back(PrivateRef);
10904 Inits.push_back(InitRef);
10905 }
10906
10907 if (Vars.empty())
10908 return nullptr;
10909
10910 Expr *StepExpr = Step;
10911 Expr *CalcStepExpr = nullptr;
10912 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
10913 !Step->isInstantiationDependent() &&
10914 !Step->containsUnexpandedParameterPack()) {
10915 SourceLocation StepLoc = Step->getLocStart();
10916 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
10917 if (Val.isInvalid())
10918 return nullptr;
10919 StepExpr = Val.get();
10920
10921 // Build var to save the step value.
10922 VarDecl *SaveVar =
10923 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
10924 ExprResult SaveRef =
10925 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
10926 ExprResult CalcStep =
10927 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
10928 CalcStep = ActOnFinishFullExpr(CalcStep.get());
10929
10930 // Warn about zero linear step (it would be probably better specified as
10931 // making corresponding variables 'const').
10932 llvm::APSInt Result;
10933 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
10934 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
10935 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
10936 << (Vars.size() > 1);
10937 if (!IsConstant && CalcStep.isUsable()) {
10938 // Calculate the step beforehand instead of doing this on each iteration.
10939 // (This is not used if the number of iterations may be kfold-ed).
10940 CalcStepExpr = CalcStep.get();
10941 }
10942 }
10943
10944 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
10945 ColonLoc, EndLoc, Vars, Privates, Inits,
10946 StepExpr, CalcStepExpr,
10947 buildPreInits(Context, ExprCaptures),
10948 buildPostUpdate(*this, ExprPostUpdates));
10949}
10950
10951static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
10952 Expr *NumIterations, Sema &SemaRef,
10953 Scope *S, DSAStackTy *Stack) {
10954 // Walk the vars and build update/final expressions for the CodeGen.
10955 SmallVector<Expr *, 8> Updates;
10956 SmallVector<Expr *, 8> Finals;
10957 Expr *Step = Clause.getStep();
10958 Expr *CalcStep = Clause.getCalcStep();
10959 // OpenMP [2.14.3.7, linear clause]
10960 // If linear-step is not specified it is assumed to be 1.
10961 if (Step == nullptr)
10962 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10963 else if (CalcStep) {
10964 Step = cast<BinaryOperator>(CalcStep)->getLHS();
10965 }
10966 bool HasErrors = false;
10967 auto CurInit = Clause.inits().begin();
10968 auto CurPrivate = Clause.privates().begin();
10969 auto LinKind = Clause.getModifier();
10970 for (auto &RefExpr : Clause.varlists()) {
10971 SourceLocation ELoc;
10972 SourceRange ERange;
10973 Expr *SimpleRefExpr = RefExpr;
10974 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
10975 /*AllowArraySection=*/false);
10976 ValueDecl *D = Res.first;
10977 if (Res.second || !D) {
10978 Updates.push_back(nullptr);
10979 Finals.push_back(nullptr);
10980 HasErrors = true;
10981 continue;
10982 }
10983 auto &&Info = Stack->isLoopControlVariable(D);
10984 // OpenMP [2.15.11, distribute simd Construct]
10985 // A list item may not appear in a linear clause, unless it is the loop
10986 // iteration variable.
10987 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
10988 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
10989 SemaRef.Diag(ELoc,
10990 diag::err_omp_linear_distribute_var_non_loop_iteration);
10991 Updates.push_back(nullptr);
10992 Finals.push_back(nullptr);
10993 HasErrors = true;
10994 continue;
10995 }
10996 Expr *InitExpr = *CurInit;
10997
10998 // Build privatized reference to the current linear var.
10999 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11000 Expr *CapturedRef;
11001 if (LinKind == OMPC_LINEAR_uval)
11002 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11003 else
11004 CapturedRef =
11005 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11006 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11007 /*RefersToCapture=*/true);
11008
11009 // Build update: Var = InitExpr + IV * Step
11010 ExprResult Update;
11011 if (!Info.first) {
11012 Update =
11013 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11014 InitExpr, IV, Step, /* Subtract */ false);
11015 } else
11016 Update = *CurPrivate;
11017 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
11018 /*DiscardedValue=*/true);
11019
11020 // Build final: Var = InitExpr + NumIterations * Step
11021 ExprResult Final;
11022 if (!Info.first) {
11023 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11024 InitExpr, NumIterations, Step,
11025 /* Subtract */ false);
11026 } else
11027 Final = *CurPrivate;
11028 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
11029 /*DiscardedValue=*/true);
11030
11031 if (!Update.isUsable() || !Final.isUsable()) {
11032 Updates.push_back(nullptr);
11033 Finals.push_back(nullptr);
11034 HasErrors = true;
11035 } else {
11036 Updates.push_back(Update.get());
11037 Finals.push_back(Final.get());
11038 }
11039 ++CurInit;
11040 ++CurPrivate;
11041 }
11042 Clause.setUpdates(Updates);
11043 Clause.setFinals(Finals);
11044 return HasErrors;
11045}
11046
11047OMPClause *Sema::ActOnOpenMPAlignedClause(
11048 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11049 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
11050
11051 SmallVector<Expr *, 8> Vars;
11052 for (auto &RefExpr : VarList) {
11053 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11053, __extension__ __PRETTY_FUNCTION__))
;
11054 SourceLocation ELoc;
11055 SourceRange ERange;
11056 Expr *SimpleRefExpr = RefExpr;
11057 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11058 /*AllowArraySection=*/false);
11059 if (Res.second) {
11060 // It will be analyzed later.
11061 Vars.push_back(RefExpr);
11062 }
11063 ValueDecl *D = Res.first;
11064 if (!D)
11065 continue;
11066
11067 QualType QType = D->getType();
11068 auto *VD = dyn_cast<VarDecl>(D);
11069
11070 // OpenMP [2.8.1, simd construct, Restrictions]
11071 // The type of list items appearing in the aligned clause must be
11072 // array, pointer, reference to array, or reference to pointer.
11073 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
11074 const Type *Ty = QType.getTypePtrOrNull();
11075 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11076 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11077 << QType << getLangOpts().CPlusPlus << ERange;
11078 bool IsDecl =
11079 !VD ||
11080 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11081 Diag(D->getLocation(),
11082 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11083 << D;
11084 continue;
11085 }
11086
11087 // OpenMP [2.8.1, simd construct, Restrictions]
11088 // A list-item cannot appear in more than one aligned clause.
11089 if (Expr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addUniqueAligned(D, SimpleRefExpr)) {
11090 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11091 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11092 << getOpenMPClauseName(OMPC_aligned);
11093 continue;
11094 }
11095
11096 DeclRefExpr *Ref = nullptr;
11097 if (!VD && IsOpenMPCapturedDecl(D))
11098 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11099 Vars.push_back(DefaultFunctionArrayConversion(
11100 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11101 .get());
11102 }
11103
11104 // OpenMP [2.8.1, simd construct, Description]
11105 // The parameter of the aligned clause, alignment, must be a constant
11106 // positive integer expression.
11107 // If no optional parameter is specified, implementation-defined default
11108 // alignments for SIMD instructions on the target platforms are assumed.
11109 if (Alignment != nullptr) {
11110 ExprResult AlignResult =
11111 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11112 if (AlignResult.isInvalid())
11113 return nullptr;
11114 Alignment = AlignResult.get();
11115 }
11116 if (Vars.empty())
11117 return nullptr;
11118
11119 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11120 EndLoc, Vars, Alignment);
11121}
11122
11123OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
11124 SourceLocation StartLoc,
11125 SourceLocation LParenLoc,
11126 SourceLocation EndLoc) {
11127 SmallVector<Expr *, 8> Vars;
11128 SmallVector<Expr *, 8> SrcExprs;
11129 SmallVector<Expr *, 8> DstExprs;
11130 SmallVector<Expr *, 8> AssignmentOps;
11131 for (auto &RefExpr : VarList) {
11132 assert(RefExpr && "NULL expr in OpenMP copyin clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP copyin clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11132, __extension__ __PRETTY_FUNCTION__))
;
11133 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11134 // It will be analyzed later.
11135 Vars.push_back(RefExpr);
11136 SrcExprs.push_back(nullptr);
11137 DstExprs.push_back(nullptr);
11138 AssignmentOps.push_back(nullptr);
11139 continue;
11140 }
11141
11142 SourceLocation ELoc = RefExpr->getExprLoc();
11143 // OpenMP [2.1, C/C++]
11144 // A list item is a variable name.
11145 // OpenMP [2.14.4.1, Restrictions, p.1]
11146 // A list item that appears in a copyin clause must be threadprivate.
11147 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
11148 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11149 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11150 << 0 << RefExpr->getSourceRange();
11151 continue;
11152 }
11153
11154 Decl *D = DE->getDecl();
11155 VarDecl *VD = cast<VarDecl>(D);
11156
11157 QualType Type = VD->getType();
11158 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11159 // It will be analyzed later.
11160 Vars.push_back(DE);
11161 SrcExprs.push_back(nullptr);
11162 DstExprs.push_back(nullptr);
11163 AssignmentOps.push_back(nullptr);
11164 continue;
11165 }
11166
11167 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11168 // A list item that appears in a copyin clause must be threadprivate.
11169 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
11170 Diag(ELoc, diag::err_omp_required_access)
11171 << getOpenMPClauseName(OMPC_copyin)
11172 << getOpenMPDirectiveName(OMPD_threadprivate);
11173 continue;
11174 }
11175
11176 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11177 // A variable of class type (or array thereof) that appears in a
11178 // copyin clause requires an accessible, unambiguous copy assignment
11179 // operator for the class type.
11180 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11181 auto *SrcVD =
11182 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11183 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11184 auto *PseudoSrcExpr = buildDeclRefExpr(
11185 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11186 auto *DstVD =
11187 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11188 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11189 auto *PseudoDstExpr =
11190 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11191 // For arrays generate assignment operation for single element and replace
11192 // it by the original array element in CodeGen.
11193 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
11194 PseudoDstExpr, PseudoSrcExpr);
11195 if (AssignmentOp.isInvalid())
11196 continue;
11197 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11198 /*DiscardedValue=*/true);
11199 if (AssignmentOp.isInvalid())
11200 continue;
11201
11202 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_copyin);
11203 Vars.push_back(DE);
11204 SrcExprs.push_back(PseudoSrcExpr);
11205 DstExprs.push_back(PseudoDstExpr);
11206 AssignmentOps.push_back(AssignmentOp.get());
11207 }
11208
11209 if (Vars.empty())
11210 return nullptr;
11211
11212 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11213 SrcExprs, DstExprs, AssignmentOps);
11214}
11215
11216OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
11217 SourceLocation StartLoc,
11218 SourceLocation LParenLoc,
11219 SourceLocation EndLoc) {
11220 SmallVector<Expr *, 8> Vars;
11221 SmallVector<Expr *, 8> SrcExprs;
11222 SmallVector<Expr *, 8> DstExprs;
11223 SmallVector<Expr *, 8> AssignmentOps;
11224 for (auto &RefExpr : VarList) {
11225 assert(RefExpr && "NULL expr in OpenMP linear clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP linear clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11225, __extension__ __PRETTY_FUNCTION__))
;
11226 SourceLocation ELoc;
11227 SourceRange ERange;
11228 Expr *SimpleRefExpr = RefExpr;
11229 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11230 /*AllowArraySection=*/false);
11231 if (Res.second) {
11232 // It will be analyzed later.
11233 Vars.push_back(RefExpr);
11234 SrcExprs.push_back(nullptr);
11235 DstExprs.push_back(nullptr);
11236 AssignmentOps.push_back(nullptr);
11237 }
11238 ValueDecl *D = Res.first;
11239 if (!D)
11240 continue;
11241
11242 QualType Type = D->getType();
11243 auto *VD = dyn_cast<VarDecl>(D);
11244
11245 // OpenMP [2.14.4.2, Restrictions, p.2]
11246 // A list item that appears in a copyprivate clause may not appear in a
11247 // private or firstprivate clause on the single construct.
11248 if (!VD || !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
11249 auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
11250 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11251 DVar.RefExpr) {
11252 Diag(ELoc, diag::err_omp_wrong_dsa)
11253 << getOpenMPClauseName(DVar.CKind)
11254 << getOpenMPClauseName(OMPC_copyprivate);
11255 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
11256 continue;
11257 }
11258
11259 // OpenMP [2.11.4.2, Restrictions, p.1]
11260 // All list items that appear in a copyprivate clause must be either
11261 // threadprivate or private in the enclosing context.
11262 if (DVar.CKind == OMPC_unknown) {
11263 DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getImplicitDSA(D, false);
11264 if (DVar.CKind == OMPC_shared) {
11265 Diag(ELoc, diag::err_omp_required_access)
11266 << getOpenMPClauseName(OMPC_copyprivate)
11267 << "threadprivate or private in the enclosing context";
11268 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
11269 continue;
11270 }
11271 }
11272 }
11273
11274 // Variably modified types are not supported.
11275 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11276 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11277 << getOpenMPClauseName(OMPC_copyprivate) << Type
11278 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
11279 bool IsDecl =
11280 !VD ||
11281 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11282 Diag(D->getLocation(),
11283 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11284 << D;
11285 continue;
11286 }
11287
11288 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11289 // A variable of class type (or array thereof) that appears in a
11290 // copyin clause requires an accessible, unambiguous copy assignment
11291 // operator for the class type.
11292 Type = Context.getBaseElementType(Type.getNonReferenceType())
11293 .getUnqualifiedType();
11294 auto *SrcVD =
11295 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11296 D->hasAttrs() ? &D->getAttrs() : nullptr);
11297 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11298 auto *DstVD =
11299 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11300 D->hasAttrs() ? &D->getAttrs() : nullptr);
11301 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11302 auto AssignmentOp = BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurScope(), ELoc, BO_Assign,
11303 PseudoDstExpr, PseudoSrcExpr);
11304 if (AssignmentOp.isInvalid())
11305 continue;
11306 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11307 /*DiscardedValue=*/true);
11308 if (AssignmentOp.isInvalid())
11309 continue;
11310
11311 // No need to mark vars as copyprivate, they are already threadprivate or
11312 // implicitly private.
11313 assert(VD || IsOpenMPCapturedDecl(D))(static_cast <bool> (VD || IsOpenMPCapturedDecl(D)) ? void
(0) : __assert_fail ("VD || IsOpenMPCapturedDecl(D)", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11313, __extension__ __PRETTY_FUNCTION__))
;
11314 Vars.push_back(
11315 VD ? RefExpr->IgnoreParens()
11316 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11317 SrcExprs.push_back(PseudoSrcExpr);
11318 DstExprs.push_back(PseudoDstExpr);
11319 AssignmentOps.push_back(AssignmentOp.get());
11320 }
11321
11322 if (Vars.empty())
11323 return nullptr;
11324
11325 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11326 Vars, SrcExprs, DstExprs, AssignmentOps);
11327}
11328
11329OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
11330 SourceLocation StartLoc,
11331 SourceLocation LParenLoc,
11332 SourceLocation EndLoc) {
11333 if (VarList.empty())
11334 return nullptr;
11335
11336 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11337}
11338
11339OMPClause *
11340Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
11341 SourceLocation DepLoc, SourceLocation ColonLoc,
11342 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11343 SourceLocation LParenLoc, SourceLocation EndLoc) {
11344 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() == OMPD_ordered &&
11345 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11346 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11347 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11348 return nullptr;
11349 }
11350 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_ordered &&
11351 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11352 DepKind == OMPC_DEPEND_sink)) {
11353 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11354 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11355 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11356 /*Last=*/OMPC_DEPEND_unknown, Except)
11357 << getOpenMPClauseName(OMPC_depend);
11358 return nullptr;
11359 }
11360 SmallVector<Expr *, 8> Vars;
11361 DSAStackTy::OperatorOffsetTy OpsOffs;
11362 llvm::APSInt DepCounter(/*BitWidth=*/32);
11363 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11364 if (DepKind == OMPC_DEPEND_sink) {
11365 if (auto *OrderedCountExpr = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam()) {
11366 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11367 TotalDepCount.setIsUnsigned(/*Val=*/true);
11368 }
11369 }
11370 for (auto &RefExpr : VarList) {
11371 assert(RefExpr && "NULL expr in OpenMP shared clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP shared clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11371, __extension__ __PRETTY_FUNCTION__))
;
11372 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11373 // It will be analyzed later.
11374 Vars.push_back(RefExpr);
11375 continue;
11376 }
11377
11378 SourceLocation ELoc = RefExpr->getExprLoc();
11379 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
11380 if (DepKind == OMPC_DEPEND_sink) {
11381 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam() &&
11382 DepCounter >= TotalDepCount) {
11383 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11384 continue;
11385 }
11386 ++DepCounter;
11387 // OpenMP [2.13.9, Summary]
11388 // depend(dependence-type : vec), where dependence-type is:
11389 // 'sink' and where vec is the iteration vector, which has the form:
11390 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11391 // where n is the value specified by the ordered clause in the loop
11392 // directive, xi denotes the loop iteration variable of the i-th nested
11393 // loop associated with the loop directive, and di is a constant
11394 // non-negative integer.
11395 if (CurContext->isDependentContext()) {
11396 // It will be analyzed later.
11397 Vars.push_back(RefExpr);
11398 continue;
11399 }
11400 SimpleExpr = SimpleExpr->IgnoreImplicit();
11401 OverloadedOperatorKind OOK = OO_None;
11402 SourceLocation OOLoc;
11403 Expr *LHS = SimpleExpr;
11404 Expr *RHS = nullptr;
11405 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11406 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11407 OOLoc = BO->getOperatorLoc();
11408 LHS = BO->getLHS()->IgnoreParenImpCasts();
11409 RHS = BO->getRHS()->IgnoreParenImpCasts();
11410 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11411 OOK = OCE->getOperator();
11412 OOLoc = OCE->getOperatorLoc();
11413 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11414 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11415 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11416 OOK = MCE->getMethodDecl()
11417 ->getNameInfo()
11418 .getName()
11419 .getCXXOverloadedOperator();
11420 OOLoc = MCE->getCallee()->getExprLoc();
11421 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11422 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11423 }
11424 SourceLocation ELoc;
11425 SourceRange ERange;
11426 auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11427 /*AllowArraySection=*/false);
11428 if (Res.second) {
11429 // It will be analyzed later.
11430 Vars.push_back(RefExpr);
11431 }
11432 ValueDecl *D = Res.first;
11433 if (!D)
11434 continue;
11435
11436 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11437 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11438 continue;
11439 }
11440 if (RHS) {
11441 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11442 RHS, OMPC_depend, /*StrictlyPositive=*/false);
11443 if (RHSRes.isInvalid())
11444 continue;
11445 }
11446 if (!CurContext->isDependentContext() &&
11447 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam() &&
11448 DepCounter != DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentLoopControlVariable(D).first) {
11449 ValueDecl *VD =
11450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(DepCounter.getZExtValue());
11451 if (VD) {
11452 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11453 << 1 << VD;
11454 } else {
11455 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11456 }
11457 continue;
11458 }
11459 OpsOffs.push_back({RHS, OOK});
11460 } else {
11461 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11462 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11463 (ASE &&
11464 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
11465 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11466 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11467 << RefExpr->getSourceRange();
11468 continue;
11469 }
11470 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11471 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11472 ExprResult Res =
11473 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
11474 getDiagnostics().setSuppressAllDiagnostics(Suppress);
11475 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11476 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11477 << RefExpr->getSourceRange();
11478 continue;
11479 }
11480 }
11481 Vars.push_back(RefExpr->IgnoreParenImpCasts());
11482 }
11483
11484 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11485 TotalDepCount > VarList.size() &&
11486 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam() &&
11487 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1)) {
11488 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
11489 << 1 << DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentLoopControlVariable(VarList.size() + 1);
11490 }
11491 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11492 Vars.empty())
11493 return nullptr;
11494
11495 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11496 DepKind, DepLoc, ColonLoc, Vars);
11497 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
11498 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion())
11499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDoacrossDependClause(C, OpsOffs);
11500 return C;
11501}
11502
11503OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
11504 SourceLocation LParenLoc,
11505 SourceLocation EndLoc) {
11506 Expr *ValExpr = Device;
11507 Stmt *HelperValStmt = nullptr;
11508
11509 // OpenMP [2.9.1, Restrictions]
11510 // The device expression must evaluate to a non-negative integer value.
11511 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11512 /*StrictlyPositive=*/false))
11513 return nullptr;
11514
11515 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
11516 OpenMPDirectiveKind CaptureRegion =
11517 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11518 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11519 ValExpr = MakeFullExpr(ValExpr).get();
11520 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11521 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11522 HelperValStmt = buildPreInits(Context, Captures);
11523 }
11524
11525 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
11526 StartLoc, LParenLoc, EndLoc);
11527}
11528
11529static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11530 DSAStackTy *Stack, QualType QTy,
11531 bool FullCheck = true) {
11532 NamedDecl *ND;
11533 if (QTy->isIncompleteType(&ND)) {
11534 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11535 return false;
11536 }
11537 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
11538 !QTy.isTrivialType(SemaRef.Context))
11539 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
11540 return true;
11541}
11542
11543/// \brief Return true if it can be proven that the provided array expression
11544/// (array section or array subscript) does NOT specify the whole size of the
11545/// array whose base type is \a BaseQTy.
11546static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
11547 const Expr *E,
11548 QualType BaseQTy) {
11549 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11550
11551 // If this is an array subscript, it refers to the whole size if the size of
11552 // the dimension is constant and equals 1. Also, an array section assumes the
11553 // format of an array subscript if no colon is used.
11554 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11555 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11556 return ATy->getSize().getSExtValue() != 1;
11557 // Size can't be evaluated statically.
11558 return false;
11559 }
11560
11561 assert(OASE && "Expecting array section if not an array subscript.")(static_cast <bool> (OASE && "Expecting array section if not an array subscript."
) ? void (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11561, __extension__ __PRETTY_FUNCTION__))
;
11562 auto *LowerBound = OASE->getLowerBound();
11563 auto *Length = OASE->getLength();
11564
11565 // If there is a lower bound that does not evaluates to zero, we are not
11566 // covering the whole dimension.
11567 if (LowerBound) {
11568 llvm::APSInt ConstLowerBound;
11569 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11570 return false; // Can't get the integer value as a constant.
11571 if (ConstLowerBound.getSExtValue())
11572 return true;
11573 }
11574
11575 // If we don't have a length we covering the whole dimension.
11576 if (!Length)
11577 return false;
11578
11579 // If the base is a pointer, we don't have a way to get the size of the
11580 // pointee.
11581 if (BaseQTy->isPointerType())
11582 return false;
11583
11584 // We can only check if the length is the same as the size of the dimension
11585 // if we have a constant array.
11586 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11587 if (!CATy)
11588 return false;
11589
11590 llvm::APSInt ConstLength;
11591 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11592 return false; // Can't get the integer value as a constant.
11593
11594 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11595}
11596
11597// Return true if it can be proven that the provided array expression (array
11598// section or array subscript) does NOT specify a single element of the array
11599// whose base type is \a BaseQTy.
11600static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
11601 const Expr *E,
11602 QualType BaseQTy) {
11603 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11604
11605 // An array subscript always refer to a single element. Also, an array section
11606 // assumes the format of an array subscript if no colon is used.
11607 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11608 return false;
11609
11610 assert(OASE && "Expecting array section if not an array subscript.")(static_cast <bool> (OASE && "Expecting array section if not an array subscript."
) ? void (0) : __assert_fail ("OASE && \"Expecting array section if not an array subscript.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11610, __extension__ __PRETTY_FUNCTION__))
;
11611 auto *Length = OASE->getLength();
11612
11613 // If we don't have a length we have to check if the array has unitary size
11614 // for this dimension. Also, we should always expect a length if the base type
11615 // is pointer.
11616 if (!Length) {
11617 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11618 return ATy->getSize().getSExtValue() != 1;
11619 // We cannot assume anything.
11620 return false;
11621 }
11622
11623 // Check if the length evaluates to 1.
11624 llvm::APSInt ConstLength;
11625 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11626 return false; // Can't get the integer value as a constant.
11627
11628 return ConstLength.getSExtValue() != 1;
11629}
11630
11631// Return the expression of the base of the mappable expression or null if it
11632// cannot be determined and do all the necessary checks to see if the expression
11633// is valid as a standalone mappable expression. In the process, record all the
11634// components of the expression.
11635static Expr *CheckMapClauseExpressionBase(
11636 Sema &SemaRef, Expr *E,
11637 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
11638 OpenMPClauseKind CKind, bool NoDiagnose) {
11639 SourceLocation ELoc = E->getExprLoc();
11640 SourceRange ERange = E->getSourceRange();
11641
11642 // The base of elements of list in a map clause have to be either:
11643 // - a reference to variable or field.
11644 // - a member expression.
11645 // - an array expression.
11646 //
11647 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11648 // reference to 'r'.
11649 //
11650 // If we have:
11651 //
11652 // struct SS {
11653 // Bla S;
11654 // foo() {
11655 // #pragma omp target map (S.Arr[:12]);
11656 // }
11657 // }
11658 //
11659 // We want to retrieve the member expression 'this->S';
11660
11661 Expr *RelevantExpr = nullptr;
11662
11663 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11664 // If a list item is an array section, it must specify contiguous storage.
11665 //
11666 // For this restriction it is sufficient that we make sure only references
11667 // to variables or fields and array expressions, and that no array sections
11668 // exist except in the rightmost expression (unless they cover the whole
11669 // dimension of the array). E.g. these would be invalid:
11670 //
11671 // r.ArrS[3:5].Arr[6:7]
11672 //
11673 // r.ArrS[3:5].x
11674 //
11675 // but these would be valid:
11676 // r.ArrS[3].Arr[6:7]
11677 //
11678 // r.ArrS[3].x
11679
11680 bool AllowUnitySizeArraySection = true;
11681 bool AllowWholeSizeArraySection = true;
11682
11683 while (!RelevantExpr) {
11684 E = E->IgnoreParenImpCasts();
11685
11686 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11687 if (!isa<VarDecl>(CurE->getDecl()))
11688 return nullptr;
11689
11690 RelevantExpr = CurE;
11691
11692 // If we got a reference to a declaration, we should not expect any array
11693 // section before that.
11694 AllowUnitySizeArraySection = false;
11695 AllowWholeSizeArraySection = false;
11696
11697 // Record the component.
11698 CurComponents.emplace_back(CurE, CurE->getDecl());
11699 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11700 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11701
11702 if (isa<CXXThisExpr>(BaseE))
11703 // We found a base expression: this->Val.
11704 RelevantExpr = CurE;
11705 else
11706 E = BaseE;
11707
11708 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11709 if (!NoDiagnose) {
11710 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11711 << CurE->getSourceRange();
11712 return nullptr;
11713 }
11714 if (RelevantExpr)
11715 return nullptr;
11716 continue;
11717 }
11718
11719 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11720
11721 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11722 // A bit-field cannot appear in a map clause.
11723 //
11724 if (FD->isBitField()) {
11725 if (!NoDiagnose) {
11726 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11727 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11728 return nullptr;
11729 }
11730 if (RelevantExpr)
11731 return nullptr;
11732 continue;
11733 }
11734
11735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11736 // If the type of a list item is a reference to a type T then the type
11737 // will be considered to be T for all purposes of this clause.
11738 QualType CurType = BaseE->getType().getNonReferenceType();
11739
11740 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11741 // A list item cannot be a variable that is a member of a structure with
11742 // a union type.
11743 //
11744 if (auto *RT = CurType->getAs<RecordType>()) {
11745 if (RT->isUnionType()) {
11746 if (!NoDiagnose) {
11747 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11748 << CurE->getSourceRange();
11749 return nullptr;
11750 }
11751 continue;
11752 }
11753 }
11754
11755 // If we got a member expression, we should not expect any array section
11756 // before that:
11757 //
11758 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11759 // If a list item is an element of a structure, only the rightmost symbol
11760 // of the variable reference can be an array section.
11761 //
11762 AllowUnitySizeArraySection = false;
11763 AllowWholeSizeArraySection = false;
11764
11765 // Record the component.
11766 CurComponents.emplace_back(CurE, FD);
11767 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11768 E = CurE->getBase()->IgnoreParenImpCasts();
11769
11770 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11771 if (!NoDiagnose) {
11772 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11773 << 0 << CurE->getSourceRange();
11774 return nullptr;
11775 }
11776 continue;
11777 }
11778
11779 // If we got an array subscript that express the whole dimension we
11780 // can have any array expressions before. If it only expressing part of
11781 // the dimension, we can only have unitary-size array expressions.
11782 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
11783 E->getType()))
11784 AllowWholeSizeArraySection = false;
11785
11786 // Record the component - we don't have any declaration associated.
11787 CurComponents.emplace_back(CurE, nullptr);
11788 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11789 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.")(static_cast <bool> (!NoDiagnose && "Array sections cannot be implicitly mapped."
) ? void (0) : __assert_fail ("!NoDiagnose && \"Array sections cannot be implicitly mapped.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11789, __extension__ __PRETTY_FUNCTION__))
;
11790 E = CurE->getBase()->IgnoreParenImpCasts();
11791
11792 QualType CurType =
11793 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11794
11795 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11796 // If the type of a list item is a reference to a type T then the type
11797 // will be considered to be T for all purposes of this clause.
11798 if (CurType->isReferenceType())
11799 CurType = CurType->getPointeeType();
11800
11801 bool IsPointer = CurType->isAnyPointerType();
11802
11803 if (!IsPointer && !CurType->isArrayType()) {
11804 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11805 << 0 << CurE->getSourceRange();
11806 return nullptr;
11807 }
11808
11809 bool NotWhole =
11810 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
11811 bool NotUnity =
11812 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
11813
11814 if (AllowWholeSizeArraySection) {
11815 // Any array section is currently allowed. Allowing a whole size array
11816 // section implies allowing a unity array section as well.
11817 //
11818 // If this array section refers to the whole dimension we can still
11819 // accept other array sections before this one, except if the base is a
11820 // pointer. Otherwise, only unitary sections are accepted.
11821 if (NotWhole || IsPointer)
11822 AllowWholeSizeArraySection = false;
11823 } else if (AllowUnitySizeArraySection && NotUnity) {
11824 // A unity or whole array section is not allowed and that is not
11825 // compatible with the properties of the current array section.
11826 SemaRef.Diag(
11827 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
11828 << CurE->getSourceRange();
11829 return nullptr;
11830 }
11831
11832 // Record the component - we don't have any declaration associated.
11833 CurComponents.emplace_back(CurE, nullptr);
11834 } else {
11835 if (!NoDiagnose) {
11836 // If nothing else worked, this is not a valid map clause expression.
11837 SemaRef.Diag(
11838 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
11839 << ERange;
11840 }
11841 return nullptr;
11842 }
11843 }
11844
11845 return RelevantExpr;
11846}
11847
11848// Return true if expression E associated with value VD has conflicts with other
11849// map information.
11850static bool CheckMapConflicts(
11851 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
11852 bool CurrentRegionOnly,
11853 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
11854 OpenMPClauseKind CKind) {
11855 assert(VD && E)(static_cast <bool> (VD && E) ? void (0) : __assert_fail
("VD && E", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11855, __extension__ __PRETTY_FUNCTION__))
;
11856 SourceLocation ELoc = E->getExprLoc();
11857 SourceRange ERange = E->getSourceRange();
11858
11859 // In order to easily check the conflicts we need to match each component of
11860 // the expression under test with the components of the expressions that are
11861 // already in the stack.
11862
11863 assert(!CurComponents.empty() && "Map clause expression with no components!")(static_cast <bool> (!CurComponents.empty() && "Map clause expression with no components!"
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11863, __extension__ __PRETTY_FUNCTION__))
;
11864 assert(CurComponents.back().getAssociatedDeclaration() == VD &&(static_cast <bool> (CurComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11865, __extension__ __PRETTY_FUNCTION__))
11865 "Map clause expression with unexpected base!")(static_cast <bool> (CurComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("CurComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11865, __extension__ __PRETTY_FUNCTION__))
;
11866
11867 // Variables to help detecting enclosing problems in data environment nests.
11868 bool IsEnclosedByDataEnvironmentExpr = false;
11869 const Expr *EnclosingExpr = nullptr;
11870
11871 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
11872 VD, CurrentRegionOnly,
11873 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
11874 StackComponents,
11875 OpenMPClauseKind) -> bool {
11876
11877 assert(!StackComponents.empty() &&(static_cast <bool> (!StackComponents.empty() &&
"Map clause expression with no components!") ? void (0) : __assert_fail
("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11878, __extension__ __PRETTY_FUNCTION__))
11878 "Map clause expression with no components!")(static_cast <bool> (!StackComponents.empty() &&
"Map clause expression with no components!") ? void (0) : __assert_fail
("!StackComponents.empty() && \"Map clause expression with no components!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11878, __extension__ __PRETTY_FUNCTION__))
;
11879 assert(StackComponents.back().getAssociatedDeclaration() == VD &&(static_cast <bool> (StackComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11880, __extension__ __PRETTY_FUNCTION__))
11880 "Map clause expression with unexpected base!")(static_cast <bool> (StackComponents.back().getAssociatedDeclaration
() == VD && "Map clause expression with unexpected base!"
) ? void (0) : __assert_fail ("StackComponents.back().getAssociatedDeclaration() == VD && \"Map clause expression with unexpected base!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11880, __extension__ __PRETTY_FUNCTION__))
;
11881
11882 // The whole expression in the stack.
11883 auto *RE = StackComponents.front().getAssociatedExpression();
11884
11885 // Expressions must start from the same base. Here we detect at which
11886 // point both expressions diverge from each other and see if we can
11887 // detect if the memory referred to both expressions is contiguous and
11888 // do not overlap.
11889 auto CI = CurComponents.rbegin();
11890 auto CE = CurComponents.rend();
11891 auto SI = StackComponents.rbegin();
11892 auto SE = StackComponents.rend();
11893 for (; CI != CE && SI != SE; ++CI, ++SI) {
11894
11895 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
11896 // At most one list item can be an array item derived from a given
11897 // variable in map clauses of the same construct.
11898 if (CurrentRegionOnly &&
11899 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
11900 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
11901 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
11902 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
11903 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
11904 diag::err_omp_multiple_array_items_in_map_clause)
11905 << CI->getAssociatedExpression()->getSourceRange();
11906 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
11907 diag::note_used_here)
11908 << SI->getAssociatedExpression()->getSourceRange();
11909 return true;
11910 }
11911
11912 // Do both expressions have the same kind?
11913 if (CI->getAssociatedExpression()->getStmtClass() !=
11914 SI->getAssociatedExpression()->getStmtClass())
11915 break;
11916
11917 // Are we dealing with different variables/fields?
11918 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
11919 break;
11920 }
11921 // Check if the extra components of the expressions in the enclosing
11922 // data environment are redundant for the current base declaration.
11923 // If they are, the maps completely overlap, which is legal.
11924 for (; SI != SE; ++SI) {
11925 QualType Type;
11926 if (auto *ASE =
11927 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
11928 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
11929 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>(
11930 SI->getAssociatedExpression())) {
11931 auto *E = OASE->getBase()->IgnoreParenImpCasts();
11932 Type =
11933 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11934 }
11935 if (Type.isNull() || Type->isAnyPointerType() ||
11936 CheckArrayExpressionDoesNotReferToWholeSize(
11937 SemaRef, SI->getAssociatedExpression(), Type))
11938 break;
11939 }
11940
11941 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11942 // List items of map clauses in the same construct must not share
11943 // original storage.
11944 //
11945 // If the expressions are exactly the same or one is a subset of the
11946 // other, it means they are sharing storage.
11947 if (CI == CE && SI == SE) {
11948 if (CurrentRegionOnly) {
11949 if (CKind == OMPC_map)
11950 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11951 else {
11952 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast <bool> (CKind == OMPC_to || CKind == OMPC_from
) ? void (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 11952, __extension__ __PRETTY_FUNCTION__))
;
11953 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11954 << ERange;
11955 }
11956 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11957 << RE->getSourceRange();
11958 return true;
11959 } else {
11960 // If we find the same expression in the enclosing data environment,
11961 // that is legal.
11962 IsEnclosedByDataEnvironmentExpr = true;
11963 return false;
11964 }
11965 }
11966
11967 QualType DerivedType =
11968 std::prev(CI)->getAssociatedDeclaration()->getType();
11969 SourceLocation DerivedLoc =
11970 std::prev(CI)->getAssociatedExpression()->getExprLoc();
11971
11972 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11973 // If the type of a list item is a reference to a type T then the type
11974 // will be considered to be T for all purposes of this clause.
11975 DerivedType = DerivedType.getNonReferenceType();
11976
11977 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
11978 // A variable for which the type is pointer and an array section
11979 // derived from that variable must not appear as list items of map
11980 // clauses of the same construct.
11981 //
11982 // Also, cover one of the cases in:
11983 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11984 // If any part of the original storage of a list item has corresponding
11985 // storage in the device data environment, all of the original storage
11986 // must have corresponding storage in the device data environment.
11987 //
11988 if (DerivedType->isAnyPointerType()) {
11989 if (CI == CE || SI == SE) {
11990 SemaRef.Diag(
11991 DerivedLoc,
11992 diag::err_omp_pointer_mapped_along_with_derived_section)
11993 << DerivedLoc;
11994 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11995 << RE->getSourceRange();
11996 return true;
11997 } else if (CI->getAssociatedExpression()->getStmtClass() !=
11998 SI->getAssociatedExpression()->getStmtClass() ||
11999 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12000 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12001 assert(CI != CE && SI != SE)(static_cast <bool> (CI != CE && SI != SE) ? void
(0) : __assert_fail ("CI != CE && SI != SE", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12001, __extension__ __PRETTY_FUNCTION__))
;
12002 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12003 << DerivedLoc;
12004 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12005 << RE->getSourceRange();
12006 return true;
12007 }
12008 }
12009
12010 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12011 // List items of map clauses in the same construct must not share
12012 // original storage.
12013 //
12014 // An expression is a subset of the other.
12015 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12016 if (CKind == OMPC_map)
12017 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12018 else {
12019 assert(CKind == OMPC_to || CKind == OMPC_from)(static_cast <bool> (CKind == OMPC_to || CKind == OMPC_from
) ? void (0) : __assert_fail ("CKind == OMPC_to || CKind == OMPC_from"
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12019, __extension__ __PRETTY_FUNCTION__))
;
12020 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12021 << ERange;
12022 }
12023 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12024 << RE->getSourceRange();
12025 return true;
12026 }
12027
12028 // The current expression uses the same base as other expression in the
12029 // data environment but does not contain it completely.
12030 if (!CurrentRegionOnly && SI != SE)
12031 EnclosingExpr = RE;
12032
12033 // The current expression is a subset of the expression in the data
12034 // environment.
12035 IsEnclosedByDataEnvironmentExpr |=
12036 (!CurrentRegionOnly && CI != CE && SI == SE);
12037
12038 return false;
12039 });
12040
12041 if (CurrentRegionOnly)
12042 return FoundError;
12043
12044 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12045 // If any part of the original storage of a list item has corresponding
12046 // storage in the device data environment, all of the original storage must
12047 // have corresponding storage in the device data environment.
12048 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12049 // If a list item is an element of a structure, and a different element of
12050 // the structure has a corresponding list item in the device data environment
12051 // prior to a task encountering the construct associated with the map clause,
12052 // then the list item must also have a corresponding list item in the device
12053 // data environment prior to the task encountering the construct.
12054 //
12055 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12056 SemaRef.Diag(ELoc,
12057 diag::err_omp_original_storage_is_shared_and_does_not_contain)
12058 << ERange;
12059 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12060 << EnclosingExpr->getSourceRange();
12061 return true;
12062 }
12063
12064 return FoundError;
12065}
12066
12067namespace {
12068// Utility struct that gathers all the related lists associated with a mappable
12069// expression.
12070struct MappableVarListInfo final {
12071 // The list of expressions.
12072 ArrayRef<Expr *> VarList;
12073 // The list of processed expressions.
12074 SmallVector<Expr *, 16> ProcessedVarList;
12075 // The mappble components for each expression.
12076 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
12077 // The base declaration of the variable.
12078 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12079
12080 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12081 // We have a list of components and base declarations for each entry in the
12082 // variable list.
12083 VarComponents.reserve(VarList.size());
12084 VarBaseDeclarations.reserve(VarList.size());
12085 }
12086};
12087}
12088
12089// Check the validity of the provided variable list for the provided clause kind
12090// \a CKind. In the check process the valid expressions, and mappable expression
12091// components and variables are extracted and used to fill \a Vars,
12092// \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12093// \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12094static void
12095checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12096 OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12097 SourceLocation StartLoc,
12098 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
12099 bool IsMapTypeImplicit = false) {
12100 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12101 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&(static_cast <bool> ((CKind == OMPC_map || CKind == OMPC_to
|| CKind == OMPC_from) && "Unexpected clause kind with mappable expressions!"
) ? void (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12102, __extension__ __PRETTY_FUNCTION__))
12102 "Unexpected clause kind with mappable expressions!")(static_cast <bool> ((CKind == OMPC_map || CKind == OMPC_to
|| CKind == OMPC_from) && "Unexpected clause kind with mappable expressions!"
) ? void (0) : __assert_fail ("(CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && \"Unexpected clause kind with mappable expressions!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12102, __extension__ __PRETTY_FUNCTION__))
;
12103
12104 // Keep track of the mappable components and base declarations in this clause.
12105 // Each entry in the list is going to have a list of components associated. We
12106 // record each set of the components so that we can build the clause later on.
12107 // In the end we should have the same amount of declarations and component
12108 // lists.
12109
12110 for (auto &RE : MVLI.VarList) {
12111 assert(RE && "Null expr in omp to/from/map clause")(static_cast <bool> (RE && "Null expr in omp to/from/map clause"
) ? void (0) : __assert_fail ("RE && \"Null expr in omp to/from/map clause\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12111, __extension__ __PRETTY_FUNCTION__))
;
12112 SourceLocation ELoc = RE->getExprLoc();
12113
12114 auto *VE = RE->IgnoreParenLValueCasts();
12115
12116 if (VE->isValueDependent() || VE->isTypeDependent() ||
12117 VE->isInstantiationDependent() ||
12118 VE->containsUnexpandedParameterPack()) {
12119 // We can only analyze this information once the missing information is
12120 // resolved.
12121 MVLI.ProcessedVarList.push_back(RE);
12122 continue;
12123 }
12124
12125 auto *SimpleExpr = RE->IgnoreParenCasts();
12126
12127 if (!RE->IgnoreParenImpCasts()->isLValue()) {
12128 SemaRef.Diag(ELoc,
12129 diag::err_omp_expected_named_var_member_or_array_expression)
12130 << RE->getSourceRange();
12131 continue;
12132 }
12133
12134 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
12135 ValueDecl *CurDeclaration = nullptr;
12136
12137 // Obtain the array or member expression bases if required. Also, fill the
12138 // components array with all the components identified in the process.
12139 auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents,
12140 CKind, /*NoDiagnose=*/false);
12141 if (!BE)
12142 continue;
12143
12144 assert(!CurComponents.empty() &&(static_cast <bool> (!CurComponents.empty() && "Invalid mappable expression information."
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12145, __extension__ __PRETTY_FUNCTION__))
12145 "Invalid mappable expression information.")(static_cast <bool> (!CurComponents.empty() && "Invalid mappable expression information."
) ? void (0) : __assert_fail ("!CurComponents.empty() && \"Invalid mappable expression information.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12145, __extension__ __PRETTY_FUNCTION__))
;
12146
12147 // For the following checks, we rely on the base declaration which is
12148 // expected to be associated with the last component. The declaration is
12149 // expected to be a variable or a field (if 'this' is being mapped).
12150 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12151 assert(CurDeclaration && "Null decl on map clause.")(static_cast <bool> (CurDeclaration && "Null decl on map clause."
) ? void (0) : __assert_fail ("CurDeclaration && \"Null decl on map clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12151, __extension__ __PRETTY_FUNCTION__))
;
12152 assert((static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12154, __extension__ __PRETTY_FUNCTION__))
12153 CurDeclaration->isCanonicalDecl() &&(static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12154, __extension__ __PRETTY_FUNCTION__))
12154 "Expecting components to have associated only canonical declarations.")(static_cast <bool> (CurDeclaration->isCanonicalDecl
() && "Expecting components to have associated only canonical declarations."
) ? void (0) : __assert_fail ("CurDeclaration->isCanonicalDecl() && \"Expecting components to have associated only canonical declarations.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12154, __extension__ __PRETTY_FUNCTION__))
;
12155
12156 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12157 auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12158
12159 assert((VD || FD) && "Only variables or fields are expected here!")(static_cast <bool> ((VD || FD) && "Only variables or fields are expected here!"
) ? void (0) : __assert_fail ("(VD || FD) && \"Only variables or fields are expected here!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12159, __extension__ __PRETTY_FUNCTION__))
;
12160 (void)FD;
12161
12162 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12163 // threadprivate variables cannot appear in a map clause.
12164 // OpenMP 4.5 [2.10.5, target update Construct]
12165 // threadprivate variables cannot appear in a from clause.
12166 if (VD && DSAS->isThreadPrivate(VD)) {
12167 auto DVar = DSAS->getTopDSA(VD, false);
12168 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12169 << getOpenMPClauseName(CKind);
12170 ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
12171 continue;
12172 }
12173
12174 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12175 // A list item cannot appear in both a map clause and a data-sharing
12176 // attribute clause on the same construct.
12177
12178 // Check conflicts with other map clause expressions. We check the conflicts
12179 // with the current construct separately from the enclosing data
12180 // environment, because the restrictions are different. We only have to
12181 // check conflicts across regions for the map clauses.
12182 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12183 /*CurrentRegionOnly=*/true, CurComponents, CKind))
12184 break;
12185 if (CKind == OMPC_map &&
12186 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12187 /*CurrentRegionOnly=*/false, CurComponents, CKind))
12188 break;
12189
12190 // OpenMP 4.5 [2.10.5, target update Construct]
12191 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12192 // If the type of a list item is a reference to a type T then the type will
12193 // be considered to be T for all purposes of this clause.
12194 QualType Type = CurDeclaration->getType().getNonReferenceType();
12195
12196 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12197 // A list item in a to or from clause must have a mappable type.
12198 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12199 // A list item must have a mappable type.
12200 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12201 DSAS, Type))
12202 continue;
12203
12204 if (CKind == OMPC_map) {
12205 // target enter data
12206 // OpenMP [2.10.2, Restrictions, p. 99]
12207 // A map-type must be specified in all map clauses and must be either
12208 // to or alloc.
12209 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12210 if (DKind == OMPD_target_enter_data &&
12211 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12212 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12213 << (IsMapTypeImplicit ? 1 : 0)
12214 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12215 << getOpenMPDirectiveName(DKind);
12216 continue;
12217 }
12218
12219 // target exit_data
12220 // OpenMP [2.10.3, Restrictions, p. 102]
12221 // A map-type must be specified in all map clauses and must be either
12222 // from, release, or delete.
12223 if (DKind == OMPD_target_exit_data &&
12224 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12225 MapType == OMPC_MAP_delete)) {
12226 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12227 << (IsMapTypeImplicit ? 1 : 0)
12228 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12229 << getOpenMPDirectiveName(DKind);
12230 continue;
12231 }
12232
12233 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12234 // A list item cannot appear in both a map clause and a data-sharing
12235 // attribute clause on the same construct
12236 if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
12237 DKind == OMPD_target_teams_distribute ||
12238 DKind == OMPD_target_teams_distribute_parallel_for ||
12239 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
12240 DKind == OMPD_target_teams_distribute_simd) && VD) {
12241 auto DVar = DSAS->getTopDSA(VD, false);
12242 if (isOpenMPPrivate(DVar.CKind)) {
12243 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12244 << getOpenMPClauseName(DVar.CKind)
12245 << getOpenMPClauseName(OMPC_map)
12246 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12247 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
12248 continue;
12249 }
12250 }
12251 }
12252
12253 // Save the current expression.
12254 MVLI.ProcessedVarList.push_back(RE);
12255
12256 // Store the components in the stack so that they can be used to check
12257 // against other clauses later on.
12258 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12259 /*WhereFoundClauseKind=*/OMPC_map);
12260
12261 // Save the components and declaration to create the clause. For purposes of
12262 // the clause creation, any component list that has has base 'this' uses
12263 // null as base declaration.
12264 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12265 MVLI.VarComponents.back().append(CurComponents.begin(),
12266 CurComponents.end());
12267 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12268 : CurDeclaration);
12269 }
12270}
12271
12272OMPClause *
12273Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
12274 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12275 SourceLocation MapLoc, SourceLocation ColonLoc,
12276 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12277 SourceLocation LParenLoc, SourceLocation EndLoc) {
12278 MappableVarListInfo MVLI(VarList);
12279 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_map, MVLI, StartLoc,
12280 MapType, IsMapTypeImplicit);
12281
12282 // We need to produce a map clause even if we don't have variables so that
12283 // other diagnostics related with non-existing map clauses are accurate.
12284 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12285 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12286 MVLI.VarComponents, MapTypeModifier, MapType,
12287 IsMapTypeImplicit, MapLoc);
12288}
12289
12290QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
12291 TypeResult ParsedType) {
12292 assert(ParsedType.isUsable())(static_cast <bool> (ParsedType.isUsable()) ? void (0) :
__assert_fail ("ParsedType.isUsable()", "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12292, __extension__ __PRETTY_FUNCTION__))
;
12293
12294 QualType ReductionType = GetTypeFromParser(ParsedType.get());
12295 if (ReductionType.isNull())
12296 return QualType();
12297
12298 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12299 // A type name in a declare reduction directive cannot be a function type, an
12300 // array type, a reference type, or a type qualified with const, volatile or
12301 // restrict.
12302 if (ReductionType.hasQualifiers()) {
12303 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12304 return QualType();
12305 }
12306
12307 if (ReductionType->isFunctionType()) {
12308 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12309 return QualType();
12310 }
12311 if (ReductionType->isReferenceType()) {
12312 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12313 return QualType();
12314 }
12315 if (ReductionType->isArrayType()) {
12316 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12317 return QualType();
12318 }
12319 return ReductionType;
12320}
12321
12322Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
12323 Scope *S, DeclContext *DC, DeclarationName Name,
12324 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12325 AccessSpecifier AS, Decl *PrevDeclInScope) {
12326 SmallVector<Decl *, 8> Decls;
12327 Decls.reserve(ReductionTypes.size());
12328
12329 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12330 forRedeclarationInCurContext());
12331 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12332 // A reduction-identifier may not be re-declared in the current scope for the
12333 // same type or for a type that is compatible according to the base language
12334 // rules.
12335 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12336 OMPDeclareReductionDecl *PrevDRD = nullptr;
12337 bool InCompoundScope = true;
12338 if (S != nullptr) {
12339 // Find previous declaration with the same name not referenced in other
12340 // declarations.
12341 FunctionScopeInfo *ParentFn = getEnclosingFunction();
12342 InCompoundScope =
12343 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12344 LookupName(Lookup, S);
12345 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12346 /*AllowInlineNamespace=*/false);
12347 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12348 auto Filter = Lookup.makeFilter();
12349 while (Filter.hasNext()) {
12350 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12351 if (InCompoundScope) {
12352 auto I = UsedAsPrevious.find(PrevDecl);
12353 if (I == UsedAsPrevious.end())
12354 UsedAsPrevious[PrevDecl] = false;
12355 if (auto *D = PrevDecl->getPrevDeclInScope())
12356 UsedAsPrevious[D] = true;
12357 }
12358 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12359 PrevDecl->getLocation();
12360 }
12361 Filter.done();
12362 if (InCompoundScope) {
12363 for (auto &PrevData : UsedAsPrevious) {
12364 if (!PrevData.second) {
12365 PrevDRD = PrevData.first;
12366 break;
12367 }
12368 }
12369 }
12370 } else if (PrevDeclInScope != nullptr) {
12371 auto *PrevDRDInScope = PrevDRD =
12372 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12373 do {
12374 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12375 PrevDRDInScope->getLocation();
12376 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12377 } while (PrevDRDInScope != nullptr);
12378 }
12379 for (auto &TyData : ReductionTypes) {
12380 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12381 bool Invalid = false;
12382 if (I != PreviousRedeclTypes.end()) {
12383 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12384 << TyData.first;
12385 Diag(I->second, diag::note_previous_definition);
12386 Invalid = true;
12387 }
12388 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12389 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12390 Name, TyData.first, PrevDRD);
12391 DC->addDecl(DRD);
12392 DRD->setAccess(AS);
12393 Decls.push_back(DRD);
12394 if (Invalid)
12395 DRD->setInvalidDecl();
12396 else
12397 PrevDRD = DRD;
12398 }
12399
12400 return DeclGroupPtrTy::make(
12401 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12402}
12403
12404void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
12405 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12406
12407 // Enter new function scope.
12408 PushFunctionScope();
12409 getCurFunction()->setHasBranchProtectedScope();
12410 getCurFunction()->setHasOMPDeclareReductionCombiner();
12411
12412 if (S != nullptr)
12413 PushDeclContext(S, DRD);
12414 else
12415 CurContext = DRD;
12416
12417 PushExpressionEvaluationContext(
12418 ExpressionEvaluationContext::PotentiallyEvaluated);
12419
12420 QualType ReductionType = DRD->getType();
12421 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12422 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12423 // uses semantics of argument handles by value, but it should be passed by
12424 // reference. C lang does not support references, so pass all parameters as
12425 // pointers.
12426 // Create 'T omp_in;' variable.
12427 auto *OmpInParm =
12428 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12429 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12430 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12431 // uses semantics of argument handles by value, but it should be passed by
12432 // reference. C lang does not support references, so pass all parameters as
12433 // pointers.
12434 // Create 'T omp_out;' variable.
12435 auto *OmpOutParm =
12436 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12437 if (S != nullptr) {
12438 PushOnScopeChains(OmpInParm, S);
12439 PushOnScopeChains(OmpOutParm, S);
12440 } else {
12441 DRD->addDecl(OmpInParm);
12442 DRD->addDecl(OmpOutParm);
12443 }
12444}
12445
12446void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
12447 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12448 DiscardCleanupsInEvaluationContext();
12449 PopExpressionEvaluationContext();
12450
12451 PopDeclContext();
12452 PopFunctionScopeInfo();
12453
12454 if (Combiner != nullptr)
12455 DRD->setCombiner(Combiner);
12456 else
12457 DRD->setInvalidDecl();
12458}
12459
12460VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
12461 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12462
12463 // Enter new function scope.
12464 PushFunctionScope();
12465 getCurFunction()->setHasBranchProtectedScope();
12466
12467 if (S != nullptr)
12468 PushDeclContext(S, DRD);
12469 else
12470 CurContext = DRD;
12471
12472 PushExpressionEvaluationContext(
12473 ExpressionEvaluationContext::PotentiallyEvaluated);
12474
12475 QualType ReductionType = DRD->getType();
12476 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12477 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12478 // uses semantics of argument handles by value, but it should be passed by
12479 // reference. C lang does not support references, so pass all parameters as
12480 // pointers.
12481 // Create 'T omp_priv;' variable.
12482 auto *OmpPrivParm =
12483 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12484 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12485 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12486 // uses semantics of argument handles by value, but it should be passed by
12487 // reference. C lang does not support references, so pass all parameters as
12488 // pointers.
12489 // Create 'T omp_orig;' variable.
12490 auto *OmpOrigParm =
12491 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12492 if (S != nullptr) {
12493 PushOnScopeChains(OmpPrivParm, S);
12494 PushOnScopeChains(OmpOrigParm, S);
12495 } else {
12496 DRD->addDecl(OmpPrivParm);
12497 DRD->addDecl(OmpOrigParm);
12498 }
12499 return OmpPrivParm;
12500}
12501
12502void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
12503 VarDecl *OmpPrivParm) {
12504 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12505 DiscardCleanupsInEvaluationContext();
12506 PopExpressionEvaluationContext();
12507
12508 PopDeclContext();
12509 PopFunctionScopeInfo();
12510
12511 if (Initializer != nullptr) {
12512 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12513 } else if (OmpPrivParm->hasInit()) {
12514 DRD->setInitializer(OmpPrivParm->getInit(),
12515 OmpPrivParm->isDirectInit()
12516 ? OMPDeclareReductionDecl::DirectInit
12517 : OMPDeclareReductionDecl::CopyInit);
12518 } else {
12519 DRD->setInvalidDecl();
12520 }
12521}
12522
12523Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
12524 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12525 for (auto *D : DeclReductions.get()) {
12526 if (IsValid) {
12527 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12528 if (S != nullptr)
12529 PushOnScopeChains(DRD, S, /*AddToContext=*/false);
12530 } else
12531 D->setInvalidDecl();
12532 }
12533 return DeclReductions;
12534}
12535
12536OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
12537 SourceLocation StartLoc,
12538 SourceLocation LParenLoc,
12539 SourceLocation EndLoc) {
12540 Expr *ValExpr = NumTeams;
12541 Stmt *HelperValStmt = nullptr;
12542
12543 // OpenMP [teams Constrcut, Restrictions]
12544 // The num_teams expression must evaluate to a positive integer value.
12545 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12546 /*StrictlyPositive=*/true))
12547 return nullptr;
12548
12549 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12550 OpenMPDirectiveKind CaptureRegion =
12551 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12552 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12553 ValExpr = MakeFullExpr(ValExpr).get();
12554 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12555 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12556 HelperValStmt = buildPreInits(Context, Captures);
12557 }
12558
12559 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12560 StartLoc, LParenLoc, EndLoc);
12561}
12562
12563OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
12564 SourceLocation StartLoc,
12565 SourceLocation LParenLoc,
12566 SourceLocation EndLoc) {
12567 Expr *ValExpr = ThreadLimit;
12568 Stmt *HelperValStmt = nullptr;
12569
12570 // OpenMP [teams Constrcut, Restrictions]
12571 // The thread_limit expression must evaluate to a positive integer value.
12572 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12573 /*StrictlyPositive=*/true))
12574 return nullptr;
12575
12576 OpenMPDirectiveKind DKind = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective();
12577 OpenMPDirectiveKind CaptureRegion =
12578 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12579 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12580 ValExpr = MakeFullExpr(ValExpr).get();
12581 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12582 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12583 HelperValStmt = buildPreInits(Context, Captures);
12584 }
12585
12586 return new (Context) OMPThreadLimitClause(
12587 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12588}
12589
12590OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
12591 SourceLocation StartLoc,
12592 SourceLocation LParenLoc,
12593 SourceLocation EndLoc) {
12594 Expr *ValExpr = Priority;
12595
12596 // OpenMP [2.9.1, task Constrcut]
12597 // The priority-value is a non-negative numerical scalar expression.
12598 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12599 /*StrictlyPositive=*/false))
12600 return nullptr;
12601
12602 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12603}
12604
12605OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
12606 SourceLocation StartLoc,
12607 SourceLocation LParenLoc,
12608 SourceLocation EndLoc) {
12609 Expr *ValExpr = Grainsize;
12610
12611 // OpenMP [2.9.2, taskloop Constrcut]
12612 // The parameter of the grainsize clause must be a positive integer
12613 // expression.
12614 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12615 /*StrictlyPositive=*/true))
12616 return nullptr;
12617
12618 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12619}
12620
12621OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
12622 SourceLocation StartLoc,
12623 SourceLocation LParenLoc,
12624 SourceLocation EndLoc) {
12625 Expr *ValExpr = NumTasks;
12626
12627 // OpenMP [2.9.2, taskloop Constrcut]
12628 // The parameter of the num_tasks clause must be a positive integer
12629 // expression.
12630 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12631 /*StrictlyPositive=*/true))
12632 return nullptr;
12633
12634 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12635}
12636
12637OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
12638 SourceLocation LParenLoc,
12639 SourceLocation EndLoc) {
12640 // OpenMP [2.13.2, critical construct, Description]
12641 // ... where hint-expression is an integer constant expression that evaluates
12642 // to a valid lock hint.
12643 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12644 if (HintExpr.isInvalid())
12645 return nullptr;
12646 return new (Context)
12647 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12648}
12649
12650OMPClause *Sema::ActOnOpenMPDistScheduleClause(
12651 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12652 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12653 SourceLocation EndLoc) {
12654 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12655 std::string Values;
12656 Values += "'";
12657 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12658 Values += "'";
12659 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12660 << Values << getOpenMPClauseName(OMPC_dist_schedule);
12661 return nullptr;
12662 }
12663 Expr *ValExpr = ChunkSize;
12664 Stmt *HelperValStmt = nullptr;
12665 if (ChunkSize) {
12666 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12667 !ChunkSize->isInstantiationDependent() &&
12668 !ChunkSize->containsUnexpandedParameterPack()) {
12669 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12670 ExprResult Val =
12671 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12672 if (Val.isInvalid())
12673 return nullptr;
12674
12675 ValExpr = Val.get();
12676
12677 // OpenMP [2.7.1, Restrictions]
12678 // chunk_size must be a loop invariant integer expression with a positive
12679 // value.
12680 llvm::APSInt Result;
12681 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12682 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12683 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12684 << "dist_schedule" << ChunkSize->getSourceRange();
12685 return nullptr;
12686 }
12687 } else if (getOpenMPCaptureRegionForClause(
12688 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective(), OMPC_dist_schedule) !=
12689 OMPD_unknown &&
12690 !CurContext->isDependentContext()) {
12691 ValExpr = MakeFullExpr(ValExpr).get();
12692 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12693 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12694 HelperValStmt = buildPreInits(Context, Captures);
12695 }
12696 }
12697 }
12698
12699 return new (Context)
12700 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12701 Kind, ValExpr, HelperValStmt);
12702}
12703
12704OMPClause *Sema::ActOnOpenMPDefaultmapClause(
12705 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
12706 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12707 SourceLocation KindLoc, SourceLocation EndLoc) {
12708 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12709 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12710 std::string Value;
12711 SourceLocation Loc;
12712 Value += "'";
12713 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12714 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12715 OMPC_DEFAULTMAP_MODIFIER_tofrom);
12716 Loc = MLoc;
12717 } else {
12718 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12719 OMPC_DEFAULTMAP_scalar);
12720 Loc = KindLoc;
12721 }
12722 Value += "'";
12723 Diag(Loc, diag::err_omp_unexpected_clause_value)
12724 << Value << getOpenMPClauseName(OMPC_defaultmap);
12725 return nullptr;
12726 }
12727 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setDefaultDMAToFromScalar(StartLoc);
12728
12729 return new (Context)
12730 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12731}
12732
12733bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
12734 DeclContext *CurLexicalContext = getCurLexicalContext();
12735 if (!CurLexicalContext->isFileContext() &&
12736 !CurLexicalContext->isExternCContext() &&
12737 !CurLexicalContext->isExternCXXContext() &&
12738 !isa<CXXRecordDecl>(CurLexicalContext) &&
12739 !isa<ClassTemplateDecl>(CurLexicalContext) &&
12740 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12741 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12742 Diag(Loc, diag::err_omp_region_not_file_context);
12743 return false;
12744 }
12745 if (IsInOpenMPDeclareTargetContext) {
12746 Diag(Loc, diag::err_omp_enclosed_declare_target);
12747 return false;
12748 }
12749
12750 IsInOpenMPDeclareTargetContext = true;
12751 return true;
12752}
12753
12754void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
12755 assert(IsInOpenMPDeclareTargetContext &&(static_cast <bool> (IsInOpenMPDeclareTargetContext &&
"Unexpected ActOnFinishOpenMPDeclareTargetDirective") ? void
(0) : __assert_fail ("IsInOpenMPDeclareTargetContext && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12756, __extension__ __PRETTY_FUNCTION__))
12756 "Unexpected ActOnFinishOpenMPDeclareTargetDirective")(static_cast <bool> (IsInOpenMPDeclareTargetContext &&
"Unexpected ActOnFinishOpenMPDeclareTargetDirective") ? void
(0) : __assert_fail ("IsInOpenMPDeclareTargetContext && \"Unexpected ActOnFinishOpenMPDeclareTargetDirective\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12756, __extension__ __PRETTY_FUNCTION__))
;
12757
12758 IsInOpenMPDeclareTargetContext = false;
12759}
12760
12761void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
12762 CXXScopeSpec &ScopeSpec,
12763 const DeclarationNameInfo &Id,
12764 OMPDeclareTargetDeclAttr::MapTypeTy MT,
12765 NamedDeclSetType &SameDirectiveDecls) {
12766 LookupResult Lookup(*this, Id, LookupOrdinaryName);
12767 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12768
12769 if (Lookup.isAmbiguous())
12770 return;
12771 Lookup.suppressDiagnostics();
12772
12773 if (!Lookup.isSingleResult()) {
12774 if (TypoCorrection Corrected =
12775 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12776 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12777 CTK_ErrorRecovery)) {
12778 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12779 << Id.getName());
12780 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12781 return;
12782 }
12783
12784 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12785 return;
12786 }
12787
12788 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12789 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12790 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12791 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
12792
12793 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
12794 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
12795 ND->addAttr(A);
12796 if (ASTMutationListener *ML = Context.getASTMutationListener())
12797 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
12798 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
12799 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
12800 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
12801 << Id.getName();
12802 }
12803 } else
12804 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
12805}
12806
12807static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
12808 Sema &SemaRef, Decl *D) {
12809 if (!D)
12810 return;
12811 const Decl *LD = nullptr;
12812 if (isa<TagDecl>(D)) {
12813 LD = cast<TagDecl>(D)->getDefinition();
12814 } else if (isa<VarDecl>(D)) {
12815 LD = cast<VarDecl>(D)->getDefinition();
12816
12817 // If this is an implicit variable that is legal and we do not need to do
12818 // anything.
12819 if (cast<VarDecl>(D)->isImplicit()) {
12820 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12821 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12822 D->addAttr(A);
12823 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12824 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12825 return;
12826 }
12827 } else if (auto *F = dyn_cast<FunctionDecl>(D)) {
12828 const FunctionDecl *FD = nullptr;
12829 if (cast<FunctionDecl>(D)->hasBody(FD)) {
12830 LD = FD;
12831 // If the definition is associated with the current declaration in the
12832 // target region (it can be e.g. a lambda) that is legal and we do not
12833 // need to do anything else.
12834 if (LD == D) {
12835 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12836 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12837 D->addAttr(A);
12838 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12839 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12840 return;
12841 }
12842 } else if (F->isFunctionTemplateSpecialization() &&
12843 F->getTemplateSpecializationKind() ==
12844 TSK_ImplicitInstantiation) {
12845 // Check if the function is implicitly instantiated from the template
12846 // defined in the declare target region.
12847 const FunctionTemplateDecl *FTD = F->getPrimaryTemplate();
12848 if (FTD && FTD->hasAttr<OMPDeclareTargetDeclAttr>())
12849 return;
12850 }
12851 }
12852 if (!LD)
12853 LD = D;
12854 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12855 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
12856 // Outlined declaration is not declared target.
12857 if (LD->isOutOfLine()) {
12858 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12859 SemaRef.Diag(SL, diag::note_used_here) << SR;
12860 } else {
12861 const DeclContext *DC = LD->getDeclContext();
12862 while (DC) {
12863 if (isa<FunctionDecl>(DC) &&
12864 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
12865 break;
12866 DC = DC->getParent();
12867 }
12868 if (DC)
12869 return;
12870
12871 // Is not declared in target context.
12872 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12873 SemaRef.Diag(SL, diag::note_used_here) << SR;
12874 }
12875 // Mark decl as declared target to prevent further diagnostic.
12876 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12877 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12878 D->addAttr(A);
12879 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12880 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12881 }
12882}
12883
12884static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
12885 Sema &SemaRef, DSAStackTy *Stack,
12886 ValueDecl *VD) {
12887 if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
12888 return true;
12889 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
12890 /*FullCheck=*/false))
12891 return false;
12892 return true;
12893}
12894
12895void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
12896 SourceLocation IdLoc) {
12897 if (!D || D->isInvalidDecl())
12898 return;
12899 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
12900 SourceLocation SL = E ? E->getLocStart() : D->getLocation();
12901 // 2.10.6: threadprivate variable cannot appear in a declare target directive.
12902 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12903 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
12904 Diag(SL, diag::err_omp_threadprivate_in_target);
12905 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false));
12906 return;
12907 }
12908 }
12909 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
12910 // Problem if any with var declared with incomplete type will be reported
12911 // as normal, so no need to check it here.
12912 if ((E || !VD->getType()->isIncompleteType()) &&
12913 !checkValueDeclInTarget(SL, SR, *this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VD)) {
12914 // Mark decl as declared target to prevent further diagnostic.
12915 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) ||
12916 isa<FunctionTemplateDecl>(VD)) {
12917 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12918 Context, OMPDeclareTargetDeclAttr::MT_To);
12919 VD->addAttr(A);
12920 if (ASTMutationListener *ML = Context.getASTMutationListener())
12921 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
12922 }
12923 return;
12924 }
12925 }
12926 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12927 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12928 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12929 OMPDeclareTargetDeclAttr::MT_Link)) {
12930 assert(IdLoc.isValid() && "Source location is expected")(static_cast <bool> (IdLoc.isValid() && "Source location is expected"
) ? void (0) : __assert_fail ("IdLoc.isValid() && \"Source location is expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12930, __extension__ __PRETTY_FUNCTION__))
;
12931 Diag(IdLoc, diag::err_omp_function_in_link_clause);
12932 Diag(FD->getLocation(), diag::note_defined_here) << FD;
12933 return;
12934 }
12935 }
12936 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
12937 if (FTD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12938 (FTD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12939 OMPDeclareTargetDeclAttr::MT_Link)) {
12940 assert(IdLoc.isValid() && "Source location is expected")(static_cast <bool> (IdLoc.isValid() && "Source location is expected"
) ? void (0) : __assert_fail ("IdLoc.isValid() && \"Source location is expected\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12940, __extension__ __PRETTY_FUNCTION__))
;
12941 Diag(IdLoc, diag::err_omp_function_in_link_clause);
12942 Diag(FTD->getLocation(), diag::note_defined_here) << FTD;
12943 return;
12944 }
12945 }
12946 if (!E) {
12947 // Checking declaration inside declare target region.
12948 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
12949 (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
12950 isa<FunctionTemplateDecl>(D))) {
12951 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12952 Context, OMPDeclareTargetDeclAttr::MT_To);
12953 D->addAttr(A);
12954 if (ASTMutationListener *ML = Context.getASTMutationListener())
12955 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12956 }
12957 return;
12958 }
12959 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
12960}
12961
12962OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
12963 SourceLocation StartLoc,
12964 SourceLocation LParenLoc,
12965 SourceLocation EndLoc) {
12966 MappableVarListInfo MVLI(VarList);
12967 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_to, MVLI, StartLoc);
12968 if (MVLI.ProcessedVarList.empty())
12969 return nullptr;
12970
12971 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12972 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12973 MVLI.VarComponents);
12974}
12975
12976OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
12977 SourceLocation StartLoc,
12978 SourceLocation LParenLoc,
12979 SourceLocation EndLoc) {
12980 MappableVarListInfo MVLI(VarList);
12981 checkMappableExpressionList(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, OMPC_from, MVLI, StartLoc);
12982 if (MVLI.ProcessedVarList.empty())
12983 return nullptr;
12984
12985 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12986 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12987 MVLI.VarComponents);
12988}
12989
12990OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
12991 SourceLocation StartLoc,
12992 SourceLocation LParenLoc,
12993 SourceLocation EndLoc) {
12994 MappableVarListInfo MVLI(VarList);
12995 SmallVector<Expr *, 8> PrivateCopies;
12996 SmallVector<Expr *, 8> Inits;
12997
12998 for (auto &RefExpr : VarList) {
12999 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP use_device_ptr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP use_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 12999, __extension__ __PRETTY_FUNCTION__))
;
13000 SourceLocation ELoc;
13001 SourceRange ERange;
13002 Expr *SimpleRefExpr = RefExpr;
13003 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13004 if (Res.second) {
13005 // It will be analyzed later.
13006 MVLI.ProcessedVarList.push_back(RefExpr);
13007 PrivateCopies.push_back(nullptr);
13008 Inits.push_back(nullptr);
13009 }
13010 ValueDecl *D = Res.first;
13011 if (!D)
13012 continue;
13013
13014 QualType Type = D->getType();
13015 Type = Type.getNonReferenceType().getUnqualifiedType();
13016
13017 auto *VD = dyn_cast<VarDecl>(D);
13018
13019 // Item should be a pointer or reference to pointer.
13020 if (!Type->isPointerType()) {
13021 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13022 << 0 << RefExpr->getSourceRange();
13023 continue;
13024 }
13025
13026 // Build the private variable and the expression that refers to it.
13027 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
13028 D->hasAttrs() ? &D->getAttrs() : nullptr);
13029 if (VDPrivate->isInvalidDecl())
13030 continue;
13031
13032 CurContext->addDecl(VDPrivate);
13033 auto VDPrivateRefExpr = buildDeclRefExpr(
13034 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13035
13036 // Add temporary variable to initialize the private copy of the pointer.
13037 auto *VDInit =
13038 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13039 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
13040 RefExpr->getExprLoc());
13041 AddInitializerToDecl(VDPrivate,
13042 DefaultLvalueConversion(VDInitRefExpr).get(),
13043 /*DirectInit=*/false);
13044
13045 // If required, build a capture to implement the privatization initialized
13046 // with the current list item value.
13047 DeclRefExpr *Ref = nullptr;
13048 if (!VD)
13049 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13050 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13051 PrivateCopies.push_back(VDPrivateRefExpr);
13052 Inits.push_back(VDInitRefExpr);
13053
13054 // We need to add a data sharing attribute for this variable to make sure it
13055 // is correctly captured. A variable that shows up in a use_device_ptr has
13056 // similar properties of a first private variable.
13057 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13058
13059 // Create a mappable component for the list item. List items in this clause
13060 // only need a component.
13061 MVLI.VarBaseDeclarations.push_back(D);
13062 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13063 MVLI.VarComponents.back().push_back(
13064 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
13065 }
13066
13067 if (MVLI.ProcessedVarList.empty())
13068 return nullptr;
13069
13070 return OMPUseDevicePtrClause::Create(
13071 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13072 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13073}
13074
13075OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
13076 SourceLocation StartLoc,
13077 SourceLocation LParenLoc,
13078 SourceLocation EndLoc) {
13079 MappableVarListInfo MVLI(VarList);
13080 for (auto &RefExpr : VarList) {
13081 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.")(static_cast <bool> (RefExpr && "NULL expr in OpenMP is_device_ptr clause."
) ? void (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP is_device_ptr clause.\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 13081, __extension__ __PRETTY_FUNCTION__))
;
13082 SourceLocation ELoc;
13083 SourceRange ERange;
13084 Expr *SimpleRefExpr = RefExpr;
13085 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13086 if (Res.second) {
13087 // It will be analyzed later.
13088 MVLI.ProcessedVarList.push_back(RefExpr);
13089 }
13090 ValueDecl *D = Res.first;
13091 if (!D)
13092 continue;
13093
13094 QualType Type = D->getType();
13095 // item should be a pointer or array or reference to pointer or array
13096 if (!Type.getNonReferenceType()->isPointerType() &&
13097 !Type.getNonReferenceType()->isArrayType()) {
13098 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13099 << 0 << RefExpr->getSourceRange();
13100 continue;
13101 }
13102
13103 // Check if the declaration in the clause does not show up in any data
13104 // sharing attribute.
13105 auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, false);
13106 if (isOpenMPPrivate(DVar.CKind)) {
13107 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13108 << getOpenMPClauseName(DVar.CKind)
13109 << getOpenMPClauseName(OMPC_is_device_ptr)
13110 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
13111 ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, D, DVar);
13112 continue;
13113 }
13114
13115 Expr *ConflictExpr;
13116 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDecl(
13117 D, /*CurrentRegionOnly=*/true,
13118 [&ConflictExpr](
13119 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
13120 OpenMPClauseKind) -> bool {
13121 ConflictExpr = R.front().getAssociatedExpression();
13122 return true;
13123 })) {
13124 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13125 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13126 << ConflictExpr->getSourceRange();
13127 continue;
13128 }
13129
13130 // Store the components in the stack so that they can be used to check
13131 // against other clauses later on.
13132 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
13133 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addMappableExpressionComponents(
13134 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13135
13136 // Record the expression we've just processed.
13137 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13138
13139 // Create a mappable component for the list item. List items in this clause
13140 // only need a component. We use a null declaration to signal fields in
13141 // 'this'.
13142 assert((isa<DeclRefExpr>(SimpleRefExpr) ||(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 13144, __extension__ __PRETTY_FUNCTION__))
13143 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 13144, __extension__ __PRETTY_FUNCTION__))
13144 "Unexpected device pointer expression!")(static_cast <bool> ((isa<DeclRefExpr>(SimpleRefExpr
) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr
)->getBase())) && "Unexpected device pointer expression!"
) ? void (0) : __assert_fail ("(isa<DeclRefExpr>(SimpleRefExpr) || isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && \"Unexpected device pointer expression!\""
, "/build/llvm-toolchain-snapshot-7~svn326551/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 13144, __extension__ __PRETTY_FUNCTION__))
;
13145 MVLI.VarBaseDeclarations.push_back(
13146 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13147 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13148 MVLI.VarComponents.back().push_back(MC);
13149 }
13150
13151 if (MVLI.ProcessedVarList.empty())
13152 return nullptr;
13153
13154 return OMPIsDevicePtrClause::Create(
13155 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13156 MVLI.VarBaseDeclarations, MVLI.VarComponents);
13157}