Bug Summary

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

Annotated Source Code

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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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-6.0~svn320940/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 DVar;
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-6.0~svn320940/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-6.0~svn320940/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 = !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1294 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1295 Level, /*NotLastprivate=*/true);
1296 }
1297
1298 // When passing data by copy, we need to make sure it fits the uintptr size
1299 // and alignment, because the runtime library only deals with uintptr types.
1300 // If it does not fit the uintptr size, we need to pass the data by reference
1301 // instead.
1302 if (!IsByRef &&
1303 (Ctx.getTypeSizeInChars(Ty) >
1304 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1305 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1306 IsByRef = true;
1307 }
1308
1309 return IsByRef;
1310}
1311
1312unsigned Sema::getOpenMPNestingLevel() const {
1313 assert(getLangOpts().OpenMP)(static_cast <bool> (getLangOpts().OpenMP) ? void (0) :
__assert_fail ("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1313, __extension__ __PRETTY_FUNCTION__))
;
1314 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
1315}
1316
1317bool Sema::isInOpenMPTargetExecutionDirective() const {
1318 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
1319 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
1320 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
1321 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1322 SourceLocation) -> bool {
1323 return isOpenMPTargetExecutionDirective(K);
1324 },
1325 false);
1326}
1327
1328VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) {
1329 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1329, __extension__ __PRETTY_FUNCTION__))
;
1330 D = getCanonicalDecl(D);
1331
1332 // If we are attempting to capture a global variable in a directive with
1333 // 'target' we return true so that this global is also mapped to the device.
1334 //
1335 // FIXME: If the declaration is enclosed in a 'declare target' directive,
1336 // then it should not be captured. Therefore, an extra check has to be
1337 // inserted here once support for 'declare target' is added.
1338 //
1339 auto *VD = dyn_cast<VarDecl>(D);
1340 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1341 return VD;
1342
1343 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
1344 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
1345 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
1346 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
1347 if (Info.first ||
1348 (VD && VD->hasLocalStorage() &&
1349 isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
1350 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
1351 return VD ? VD : Info.second;
1352 auto DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
1353 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1354 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1355 DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(
1356 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1357 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
1358 if (DVarPrivate.CKind != OMPC_unknown)
1359 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1360 }
1361 return nullptr;
1362}
1363
1364void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1365 unsigned Level) const {
1366 SmallVector<OpenMPDirectiveKind, 4> Regions;
1367 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
1368 FunctionScopesIndex -= Regions.size();
1369}
1370
1371bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) {
1372 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1372, __extension__ __PRETTY_FUNCTION__))
;
1373 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1374 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1375 Level) ||
1376 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
1377 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
1378 // Consider taskgroup reduction descriptor variable a private to avoid
1379 // possible capture in the region.
1380 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
1381 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1382 Level) &&
1383 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level));
1384}
1385
1386void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) {
1387 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1387, __extension__ __PRETTY_FUNCTION__))
;
1388 D = getCanonicalDecl(D);
1389 OpenMPClauseKind OMPC = OMPC_unknown;
1390 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
1391 const unsigned NewLevel = I - 1;
1392 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
1393 [&OMPC](const OpenMPClauseKind K) {
1394 if (isOpenMPPrivate(K)) {
1395 OMPC = K;
1396 return true;
1397 }
1398 return false;
1399 },
1400 NewLevel))
1401 break;
1402 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1403 D, NewLevel,
1404 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1405 OpenMPClauseKind) { return true; })) {
1406 OMPC = OMPC_map;
1407 break;
1408 }
1409 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1410 NewLevel)) {
1411 OMPC = OMPC_firstprivate;
1412 break;
1413 }
1414 }
1415 if (OMPC != OMPC_unknown)
1416 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1417}
1418
1419bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) {
1420 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1420, __extension__ __PRETTY_FUNCTION__))
;
1421 // Return true if the current level is no longer enclosed in a target region.
1422
1423 auto *VD = dyn_cast<VarDecl>(D);
1424 return VD && !VD->hasLocalStorage() &&
1425 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1426 Level);
1427}
1428
1429void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
1430
1431void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1432 const DeclarationNameInfo &DirName,
1433 Scope *CurScope, SourceLocation Loc) {
1434 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
1435 PushExpressionEvaluationContext(
1436 ExpressionEvaluationContext::PotentiallyEvaluated);
1437}
1438
1439void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1440 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
1441}
1442
1443void Sema::EndOpenMPClause() {
1444 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
1445}
1446
1447void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1448 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1449 // A variable of class type (or array thereof) that appears in a lastprivate
1450 // clause requires an accessible, unambiguous default constructor for the
1451 // class type, unless the list item is also specified in a firstprivate
1452 // clause.
1453 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1454 for (auto *C : D->clauses()) {
1455 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1456 SmallVector<Expr *, 8> PrivateCopies;
1457 for (auto *DE : Clause->varlists()) {
1458 if (DE->isValueDependent() || DE->isTypeDependent()) {
1459 PrivateCopies.push_back(nullptr);
1460 continue;
1461 }
1462 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1463 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1464 QualType Type = VD->getType().getNonReferenceType();
1465 auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, false);
1466 if (DVar.CKind == OMPC_lastprivate) {
1467 // Generate helper private variable and initialize it with the
1468 // default value. The address of the original variable is replaced
1469 // by the address of the new private variable in CodeGen. This new
1470 // variable is not added to IdResolver, so the code in the OpenMP
1471 // region uses original variable for proper diagnostics.
1472 auto *VDPrivate = buildVarDecl(
1473 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1474 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1475 ActOnUninitializedDecl(VDPrivate);
1476 if (VDPrivate->isInvalidDecl())
1477 continue;
1478 PrivateCopies.push_back(buildDeclRefExpr(
1479 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1480 } else {
1481 // The variable is also a firstprivate, so initialization sequence
1482 // for private copy is generated already.
1483 PrivateCopies.push_back(nullptr);
1484 }
1485 }
1486 // Set initializers to private copies if no errors were found.
1487 if (PrivateCopies.size() == Clause->varlist_size())
1488 Clause->setPrivateCopies(PrivateCopies);
1489 }
1490 }
1491 }
1492
1493 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
1494 DiscardCleanupsInEvaluationContext();
1495 PopExpressionEvaluationContext();
1496}
1497
1498static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1499 Expr *NumIterations, Sema &SemaRef,
1500 Scope *S, DSAStackTy *Stack);
1501
1502namespace {
1503
1504class VarDeclFilterCCC : public CorrectionCandidateCallback {
1505private:
1506 Sema &SemaRef;
1507
1508public:
1509 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1510 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1511 NamedDecl *ND = Candidate.getCorrectionDecl();
1512 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1513 return VD->hasGlobalStorage() &&
1514 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1515 SemaRef.getCurScope());
1516 }
1517 return false;
1518 }
1519};
1520
1521class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1522private:
1523 Sema &SemaRef;
1524
1525public:
1526 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1527 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1528 NamedDecl *ND = Candidate.getCorrectionDecl();
1529 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1530 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1531 SemaRef.getCurScope());
1532 }
1533 return false;
1534 }
1535};
1536
1537} // namespace
1538
1539ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1540 CXXScopeSpec &ScopeSpec,
1541 const DeclarationNameInfo &Id) {
1542 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1543 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1544
1545 if (Lookup.isAmbiguous())
1546 return ExprError();
1547
1548 VarDecl *VD;
1549 if (!Lookup.isSingleResult()) {
1550 if (TypoCorrection Corrected = CorrectTypo(
1551 Id, LookupOrdinaryName, CurScope, nullptr,
1552 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1553 diagnoseTypo(Corrected,
1554 PDiag(Lookup.empty()
1555 ? diag::err_undeclared_var_use_suggest
1556 : diag::err_omp_expected_var_arg_suggest)
1557 << Id.getName());
1558 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1559 } else {
1560 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1561 : diag::err_omp_expected_var_arg)
1562 << Id.getName();
1563 return ExprError();
1564 }
1565 } else {
1566 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1567 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1568 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1569 return ExprError();
1570 }
1571 }
1572 Lookup.suppressDiagnostics();
1573
1574 // OpenMP [2.9.2, Syntax, C/C++]
1575 // Variables must be file-scope, namespace-scope, or static block-scope.
1576 if (!VD->hasGlobalStorage()) {
1577 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1578 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1579 bool IsDecl =
1580 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1581 Diag(VD->getLocation(),
1582 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1583 << VD;
1584 return ExprError();
1585 }
1586
1587 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1588 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1589 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1590 // A threadprivate directive for file-scope variables must appear outside
1591 // any definition or declaration.
1592 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1593 !getCurLexicalContext()->isTranslationUnit()) {
1594 Diag(Id.getLoc(), diag::err_omp_var_scope)
1595 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1596 bool IsDecl =
1597 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1598 Diag(VD->getLocation(),
1599 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1600 << VD;
1601 return ExprError();
1602 }
1603 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1604 // A threadprivate directive for static class member variables must appear
1605 // in the class definition, in the same scope in which the member
1606 // variables are declared.
1607 if (CanonicalVD->isStaticDataMember() &&
1608 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1609 Diag(Id.getLoc(), diag::err_omp_var_scope)
1610 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1611 bool IsDecl =
1612 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1613 Diag(VD->getLocation(),
1614 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1615 << VD;
1616 return ExprError();
1617 }
1618 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1619 // A threadprivate directive for namespace-scope variables must appear
1620 // outside any definition or declaration other than the namespace
1621 // definition itself.
1622 if (CanonicalVD->getDeclContext()->isNamespace() &&
1623 (!getCurLexicalContext()->isFileContext() ||
1624 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1625 Diag(Id.getLoc(), diag::err_omp_var_scope)
1626 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1627 bool IsDecl =
1628 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1629 Diag(VD->getLocation(),
1630 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1631 << VD;
1632 return ExprError();
1633 }
1634 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1635 // A threadprivate directive for static block-scope variables must appear
1636 // in the scope of the variable and not in a nested scope.
1637 if (CanonicalVD->isStaticLocal() && CurScope &&
1638 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1639 Diag(Id.getLoc(), diag::err_omp_var_scope)
1640 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1641 bool IsDecl =
1642 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1643 Diag(VD->getLocation(),
1644 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1645 << VD;
1646 return ExprError();
1647 }
1648
1649 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1650 // A threadprivate directive must lexically precede all references to any
1651 // of the variables in its list.
1652 if (VD->isUsed() && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
1653 Diag(Id.getLoc(), diag::err_omp_var_used)
1654 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1655 return ExprError();
1656 }
1657
1658 QualType ExprType = VD->getType().getNonReferenceType();
1659 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1660 SourceLocation(), VD,
1661 /*RefersToEnclosingVariableOrCapture=*/false,
1662 Id.getLoc(), ExprType, VK_LValue);
1663}
1664
1665Sema::DeclGroupPtrTy
1666Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1667 ArrayRef<Expr *> VarList) {
1668 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1669 CurContext->addDecl(D);
1670 return DeclGroupPtrTy::make(DeclGroupRef(D));
1671 }
1672 return nullptr;
1673}
1674
1675namespace {
1676class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1677 Sema &SemaRef;
1678
1679public:
1680 bool VisitDeclRefExpr(const DeclRefExpr *E) {
1681 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1682 if (VD->hasLocalStorage()) {
1683 SemaRef.Diag(E->getLocStart(),
1684 diag::err_omp_local_var_in_threadprivate_init)
1685 << E->getSourceRange();
1686 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1687 << VD << VD->getSourceRange();
1688 return true;
1689 }
1690 }
1691 return false;
1692 }
1693 bool VisitStmt(const Stmt *S) {
1694 for (auto Child : S->children()) {
1695 if (Child && Visit(Child))
1696 return true;
1697 }
1698 return false;
1699 }
1700 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1701};
1702} // namespace
1703
1704OMPThreadPrivateDecl *
1705Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1706 SmallVector<Expr *, 8> Vars;
1707 for (auto &RefExpr : VarList) {
1708 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1709 VarDecl *VD = cast<VarDecl>(DE->getDecl());
1710 SourceLocation ILoc = DE->getExprLoc();
1711
1712 // Mark variable as used.
1713 VD->setReferenced();
1714 VD->markUsed(Context);
1715
1716 QualType QType = VD->getType();
1717 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1718 // It will be analyzed later.
1719 Vars.push_back(DE);
1720 continue;
1721 }
1722
1723 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1724 // A threadprivate variable must not have an incomplete type.
1725 if (RequireCompleteType(ILoc, VD->getType(),
1726 diag::err_omp_threadprivate_incomplete_type)) {
1727 continue;
1728 }
1729
1730 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1731 // A threadprivate variable must not have a reference type.
1732 if (VD->getType()->isReferenceType()) {
1733 Diag(ILoc, diag::err_omp_ref_type_arg)
1734 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1735 bool IsDecl =
1736 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1737 Diag(VD->getLocation(),
1738 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1739 << VD;
1740 continue;
1741 }
1742
1743 // Check if this is a TLS variable. If TLS is not being supported, produce
1744 // the corresponding diagnostic.
1745 if ((VD->getTLSKind() != VarDecl::TLS_None &&
1746 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1747 getLangOpts().OpenMPUseTLS &&
1748 getASTContext().getTargetInfo().isTLSSupported())) ||
1749 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1750 !VD->isLocalVarDecl())) {
1751 Diag(ILoc, diag::err_omp_var_thread_local)
1752 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1753 bool IsDecl =
1754 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1755 Diag(VD->getLocation(),
1756 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1757 << VD;
1758 continue;
1759 }
1760
1761 // Check if initial value of threadprivate variable reference variable with
1762 // local storage (it is not supported by runtime).
1763 if (auto Init = VD->getAnyInitializer()) {
1764 LocalVarRefChecker Checker(*this);
1765 if (Checker.Visit(Init))
1766 continue;
1767 }
1768
1769 Vars.push_back(RefExpr);
1770 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
1771 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1772 Context, SourceRange(Loc, Loc)));
1773 if (auto *ML = Context.getASTMutationListener())
1774 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1775 }
1776 OMPThreadPrivateDecl *D = nullptr;
1777 if (!Vars.empty()) {
1778 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1779 Vars);
1780 D->setAccess(AS_public);
1781 }
1782 return D;
1783}
1784
1785static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1786 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1787 bool IsLoopIterVar = false) {
1788 if (DVar.RefExpr) {
1789 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1790 << getOpenMPClauseName(DVar.CKind);
1791 return;
1792 }
1793 enum {
1794 PDSA_StaticMemberShared,
1795 PDSA_StaticLocalVarShared,
1796 PDSA_LoopIterVarPrivate,
1797 PDSA_LoopIterVarLinear,
1798 PDSA_LoopIterVarLastprivate,
1799 PDSA_ConstVarShared,
1800 PDSA_GlobalVarShared,
1801 PDSA_TaskVarFirstprivate,
1802 PDSA_LocalVarPrivate,
1803 PDSA_Implicit
1804 } Reason = PDSA_Implicit;
1805 bool ReportHint = false;
1806 auto ReportLoc = D->getLocation();
1807 auto *VD = dyn_cast<VarDecl>(D);
1808 if (IsLoopIterVar) {
1809 if (DVar.CKind == OMPC_private)
1810 Reason = PDSA_LoopIterVarPrivate;
1811 else if (DVar.CKind == OMPC_lastprivate)
1812 Reason = PDSA_LoopIterVarLastprivate;
1813 else
1814 Reason = PDSA_LoopIterVarLinear;
1815 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1816 DVar.CKind == OMPC_firstprivate) {
1817 Reason = PDSA_TaskVarFirstprivate;
1818 ReportLoc = DVar.ImplicitDSALoc;
1819 } else if (VD && VD->isStaticLocal())
1820 Reason = PDSA_StaticLocalVarShared;
1821 else if (VD && VD->isStaticDataMember())
1822 Reason = PDSA_StaticMemberShared;
1823 else if (VD && VD->isFileVarDecl())
1824 Reason = PDSA_GlobalVarShared;
1825 else if (D->getType().isConstant(SemaRef.getASTContext()))
1826 Reason = PDSA_ConstVarShared;
1827 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1828 ReportHint = true;
1829 Reason = PDSA_LocalVarPrivate;
1830 }
1831 if (Reason != PDSA_Implicit) {
1832 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1833 << Reason << ReportHint
1834 << getOpenMPDirectiveName(Stack->getCurrentDirective());
1835 } else if (DVar.ImplicitDSALoc.isValid()) {
1836 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1837 << getOpenMPClauseName(DVar.CKind);
1838 }
1839}
1840
1841namespace {
1842class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1843 DSAStackTy *Stack;
1844 Sema &SemaRef;
1845 bool ErrorFound;
1846 CapturedStmt *CS;
1847 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1848 llvm::SmallVector<Expr *, 8> ImplicitMap;
1849 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1850 llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1851
1852public:
1853 void VisitDeclRefExpr(DeclRefExpr *E) {
1854 if (E->isTypeDependent() || E->isValueDependent() ||
1855 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1856 return;
1857 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1858 VD = VD->getCanonicalDecl();
1859 // Skip internally declared variables.
1860 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1861 return;
1862
1863 auto DVar = Stack->getTopDSA(VD, false);
1864 // Check if the variable has explicit DSA set and stop analysis if it so.
1865 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1866 return;
1867
1868 // Skip internally declared static variables.
1869 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1870 return;
1871
1872 auto ELoc = E->getExprLoc();
1873 auto DKind = Stack->getCurrentDirective();
1874 // The default(none) clause requires that each variable that is referenced
1875 // in the construct, and does not have a predetermined data-sharing
1876 // attribute, must have its data-sharing attribute explicitly determined
1877 // by being listed in a data-sharing attribute clause.
1878 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1879 isParallelOrTaskRegion(DKind) &&
1880 VarsWithInheritedDSA.count(VD) == 0) {
1881 VarsWithInheritedDSA[VD] = E;
1882 return;
1883 }
1884
1885 if (isOpenMPTargetExecutionDirective(DKind) &&
1886 !Stack->isLoopControlVariable(VD).first) {
1887 if (!Stack->checkMappableExprComponentListsForDecl(
1888 VD, /*CurrentRegionOnly=*/true,
1889 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1890 StackComponents,
1891 OpenMPClauseKind) {
1892 // Variable is used if it has been marked as an array, array
1893 // section or the variable iself.
1894 return StackComponents.size() == 1 ||
1895 std::all_of(
1896 std::next(StackComponents.rbegin()),
1897 StackComponents.rend(),
1898 [](const OMPClauseMappableExprCommon::
1899 MappableComponent &MC) {
1900 return MC.getAssociatedDeclaration() ==
1901 nullptr &&
1902 (isa<OMPArraySectionExpr>(
1903 MC.getAssociatedExpression()) ||
1904 isa<ArraySubscriptExpr>(
1905 MC.getAssociatedExpression()));
1906 });
1907 })) {
1908 bool IsFirstprivate = false;
1909 // By default lambdas are captured as firstprivates.
1910 if (const auto *RD =
1911 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1912 IsFirstprivate = RD->isLambda();
1913 IsFirstprivate =
1914 IsFirstprivate ||
1915 (VD->getType().getNonReferenceType()->isScalarType() &&
1916 Stack->getDefaultDMA() != DMA_tofrom_scalar);
1917 if (IsFirstprivate)
1918 ImplicitFirstprivate.emplace_back(E);
1919 else
1920 ImplicitMap.emplace_back(E);
1921 return;
1922 }
1923 }
1924
1925 // OpenMP [2.9.3.6, Restrictions, p.2]
1926 // A list item that appears in a reduction clause of the innermost
1927 // enclosing worksharing or parallel construct may not be accessed in an
1928 // explicit task.
1929 DVar = Stack->hasInnermostDSA(
1930 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1931 [](OpenMPDirectiveKind K) -> bool {
1932 return isOpenMPParallelDirective(K) ||
1933 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1934 },
1935 /*FromParent=*/true);
1936 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1937 ErrorFound = true;
1938 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1939 ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1940 return;
1941 }
1942
1943 // Define implicit data-sharing attributes for task.
1944 DVar = Stack->getImplicitDSA(VD, false);
1945 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1946 !Stack->isLoopControlVariable(VD).first)
1947 ImplicitFirstprivate.push_back(E);
1948 }
1949 }
1950 void VisitMemberExpr(MemberExpr *E) {
1951 if (E->isTypeDependent() || E->isValueDependent() ||
1952 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1953 return;
1954 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1955 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1956 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1957 if (!FD)
1958 return;
1959 auto DVar = Stack->getTopDSA(FD, false);
1960 // Check if the variable has explicit DSA set and stop analysis if it
1961 // so.
1962 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1963 return;
1964
1965 if (isOpenMPTargetExecutionDirective(DKind) &&
1966 !Stack->isLoopControlVariable(FD).first &&
1967 !Stack->checkMappableExprComponentListsForDecl(
1968 FD, /*CurrentRegionOnly=*/true,
1969 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1970 StackComponents,
1971 OpenMPClauseKind) {
1972 return isa<CXXThisExpr>(
1973 cast<MemberExpr>(
1974 StackComponents.back().getAssociatedExpression())
1975 ->getBase()
1976 ->IgnoreParens());
1977 })) {
1978 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1979 // A bit-field cannot appear in a map clause.
1980 //
1981 if (FD->isBitField())
1982 return;
1983 ImplicitMap.emplace_back(E);
1984 return;
1985 }
1986
1987 auto ELoc = E->getExprLoc();
1988 // OpenMP [2.9.3.6, Restrictions, p.2]
1989 // A list item that appears in a reduction clause of the innermost
1990 // enclosing worksharing or parallel construct may not be accessed in
1991 // an explicit task.
1992 DVar = Stack->hasInnermostDSA(
1993 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1994 [](OpenMPDirectiveKind K) -> bool {
1995 return isOpenMPParallelDirective(K) ||
1996 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1997 },
1998 /*FromParent=*/true);
1999 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2000 ErrorFound = true;
2001 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2002 ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2003 return;
2004 }
2005
2006 // Define implicit data-sharing attributes for task.
2007 DVar = Stack->getImplicitDSA(FD, false);
2008 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2009 !Stack->isLoopControlVariable(FD).first)
2010 ImplicitFirstprivate.push_back(E);
2011 return;
2012 }
2013 if (isOpenMPTargetExecutionDirective(DKind)) {
2014 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2015 if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2016 /*NoDiagnose=*/true))
2017 return;
2018 auto *VD = cast<ValueDecl>(
2019 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2020 if (!Stack->checkMappableExprComponentListsForDecl(
2021 VD, /*CurrentRegionOnly=*/true,
2022 [&CurComponents](
2023 OMPClauseMappableExprCommon::MappableExprComponentListRef
2024 StackComponents,
2025 OpenMPClauseKind) {
2026 auto CCI = CurComponents.rbegin();
2027 auto CCE = CurComponents.rend();
2028 for (const auto &SC : llvm::reverse(StackComponents)) {
2029 // Do both expressions have the same kind?
2030 if (CCI->getAssociatedExpression()->getStmtClass() !=
2031 SC.getAssociatedExpression()->getStmtClass())
2032 if (!(isa<OMPArraySectionExpr>(
2033 SC.getAssociatedExpression()) &&
2034 isa<ArraySubscriptExpr>(
2035 CCI->getAssociatedExpression())))
2036 return false;
2037
2038 Decl *CCD = CCI->getAssociatedDeclaration();
2039 Decl *SCD = SC.getAssociatedDeclaration();
2040 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2041 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2042 if (SCD != CCD)
2043 return false;
2044 std::advance(CCI, 1);
2045 if (CCI == CCE)
2046 break;
2047 }
2048 return true;
2049 })) {
2050 Visit(E->getBase());
2051 }
2052 } else
2053 Visit(E->getBase());
2054 }
2055 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2056 for (auto *C : S->clauses()) {
2057 // Skip analysis of arguments of implicitly defined firstprivate clause
2058 // for task|target directives.
2059 // Skip analysis of arguments of implicitly defined map clause for target
2060 // directives.
2061 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2062 C->isImplicit())) {
2063 for (auto *CC : C->children()) {
2064 if (CC)
2065 Visit(CC);
2066 }
2067 }
2068 }
2069 }
2070 void VisitStmt(Stmt *S) {
2071 for (auto *C : S->children()) {
2072 if (C && !isa<OMPExecutableDirective>(C))
2073 Visit(C);
2074 }
2075 }
2076
2077 bool isErrorFound() { return ErrorFound; }
2078 ArrayRef<Expr *> getImplicitFirstprivate() const {
2079 return ImplicitFirstprivate;
2080 }
2081 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2082 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2083 return VarsWithInheritedDSA;
2084 }
2085
2086 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2087 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2088};
2089} // namespace
2090
2091void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2092 switch (DKind) {
2093 case OMPD_parallel:
2094 case OMPD_parallel_for:
2095 case OMPD_parallel_for_simd:
2096 case OMPD_parallel_sections:
2097 case OMPD_teams:
2098 case OMPD_teams_distribute:
2099 case OMPD_teams_distribute_simd: {
2100 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2101 QualType KmpInt32PtrTy =
2102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2103 Sema::CapturedParamNameType Params[] = {
2104 std::make_pair(".global_tid.", KmpInt32PtrTy),
2105 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2106 std::make_pair(StringRef(), QualType()) // __context with shared vars
2107 };
2108 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2109 Params);
2110 break;
2111 }
2112 case OMPD_target_teams:
2113 case OMPD_target_parallel:
2114 case OMPD_target_parallel_for:
2115 case OMPD_target_parallel_for_simd:
2116 case OMPD_target_teams_distribute:
2117 case OMPD_target_teams_distribute_simd: {
2118 Sema::CapturedParamNameType ParamsTarget[] = {
2119 std::make_pair(StringRef(), QualType()) // __context with shared vars
2120 };
2121 // Start a captured region for 'target' with no implicit parameters.
2122 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2123 ParamsTarget);
2124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2125 QualType KmpInt32PtrTy =
2126 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2127 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2128 std::make_pair(".global_tid.", KmpInt32PtrTy),
2129 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2130 std::make_pair(StringRef(), QualType()) // __context with shared vars
2131 };
2132 // Start a captured region for 'teams' or 'parallel'. Both regions have
2133 // the same implicit parameters.
2134 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2135 ParamsTeamsOrParallel);
2136 break;
2137 }
2138 case OMPD_simd:
2139 case OMPD_for:
2140 case OMPD_for_simd:
2141 case OMPD_sections:
2142 case OMPD_section:
2143 case OMPD_single:
2144 case OMPD_master:
2145 case OMPD_critical:
2146 case OMPD_taskgroup:
2147 case OMPD_distribute:
2148 case OMPD_distribute_simd:
2149 case OMPD_ordered:
2150 case OMPD_atomic:
2151 case OMPD_target_data:
2152 case OMPD_target:
2153 case OMPD_target_simd: {
2154 Sema::CapturedParamNameType Params[] = {
2155 std::make_pair(StringRef(), QualType()) // __context with shared vars
2156 };
2157 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2158 Params);
2159 break;
2160 }
2161 case OMPD_task: {
2162 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2163 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2164 FunctionProtoType::ExtProtoInfo EPI;
2165 EPI.Variadic = true;
2166 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2167 Sema::CapturedParamNameType Params[] = {
2168 std::make_pair(".global_tid.", KmpInt32Ty),
2169 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2170 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2171 std::make_pair(".copy_fn.",
2172 Context.getPointerType(CopyFnType).withConst()),
2173 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2174 std::make_pair(StringRef(), QualType()) // __context with shared vars
2175 };
2176 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2177 Params);
2178 // Mark this captured region as inlined, because we don't use outlined
2179 // function directly.
2180 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2181 AlwaysInlineAttr::CreateImplicit(
2182 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2183 break;
2184 }
2185 case OMPD_taskloop:
2186 case OMPD_taskloop_simd: {
2187 QualType KmpInt32Ty =
2188 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2189 QualType KmpUInt64Ty =
2190 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2191 QualType KmpInt64Ty =
2192 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2193 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2194 FunctionProtoType::ExtProtoInfo EPI;
2195 EPI.Variadic = true;
2196 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2197 Sema::CapturedParamNameType Params[] = {
2198 std::make_pair(".global_tid.", KmpInt32Ty),
2199 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2200 std::make_pair(".privates.",
2201 Context.VoidPtrTy.withConst().withRestrict()),
2202 std::make_pair(
2203 ".copy_fn.",
2204 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2205 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2206 std::make_pair(".lb.", KmpUInt64Ty),
2207 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2208 std::make_pair(".liter.", KmpInt32Ty),
2209 std::make_pair(".reductions.",
2210 Context.VoidPtrTy.withConst().withRestrict()),
2211 std::make_pair(StringRef(), QualType()) // __context with shared vars
2212 };
2213 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2214 Params);
2215 // Mark this captured region as inlined, because we don't use outlined
2216 // function directly.
2217 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2218 AlwaysInlineAttr::CreateImplicit(
2219 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2220 break;
2221 }
2222 case OMPD_distribute_parallel_for_simd:
2223 case OMPD_distribute_parallel_for:
2224 case OMPD_target_teams_distribute_parallel_for:
2225 case OMPD_target_teams_distribute_parallel_for_simd: {
2226 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2227 QualType KmpInt32PtrTy =
2228 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2229 Sema::CapturedParamNameType Params[] = {
2230 std::make_pair(".global_tid.", KmpInt32PtrTy),
2231 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2232 std::make_pair(".previous.lb.", Context.getSizeType()),
2233 std::make_pair(".previous.ub.", Context.getSizeType()),
2234 std::make_pair(StringRef(), QualType()) // __context with shared vars
2235 };
2236 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2237 Params);
2238 break;
2239 }
2240 case OMPD_teams_distribute_parallel_for:
2241 case OMPD_teams_distribute_parallel_for_simd: {
2242 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2243 QualType KmpInt32PtrTy =
2244 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2245
2246 Sema::CapturedParamNameType ParamsTeams[] = {
2247 std::make_pair(".global_tid.", KmpInt32PtrTy),
2248 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2249 std::make_pair(StringRef(), QualType()) // __context with shared vars
2250 };
2251 // Start a captured region for 'target' with no implicit parameters.
2252 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2253 ParamsTeams);
2254
2255 Sema::CapturedParamNameType ParamsParallel[] = {
2256 std::make_pair(".global_tid.", KmpInt32PtrTy),
2257 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2258 std::make_pair(".previous.lb.", Context.getSizeType()),
2259 std::make_pair(".previous.ub.", Context.getSizeType()),
2260 std::make_pair(StringRef(), QualType()) // __context with shared vars
2261 };
2262 // Start a captured region for 'teams' or 'parallel'. Both regions have
2263 // the same implicit parameters.
2264 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2265 ParamsParallel);
2266 break;
2267 }
2268 case OMPD_target_update:
2269 case OMPD_target_enter_data:
2270 case OMPD_target_exit_data: {
2271 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2272 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2273 FunctionProtoType::ExtProtoInfo EPI;
2274 EPI.Variadic = true;
2275 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2276 Sema::CapturedParamNameType Params[] = {
2277 std::make_pair(".global_tid.", KmpInt32Ty),
2278 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2279 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2280 std::make_pair(".copy_fn.",
2281 Context.getPointerType(CopyFnType).withConst()),
2282 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2283 std::make_pair(StringRef(), QualType()) // __context with shared vars
2284 };
2285 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2286 Params);
2287 // Mark this captured region as inlined, because we don't use outlined
2288 // function directly.
2289 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2290 AlwaysInlineAttr::CreateImplicit(
2291 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2292 break;
2293 }
2294 case OMPD_threadprivate:
2295 case OMPD_taskyield:
2296 case OMPD_barrier:
2297 case OMPD_taskwait:
2298 case OMPD_cancellation_point:
2299 case OMPD_cancel:
2300 case OMPD_flush:
2301 case OMPD_declare_reduction:
2302 case OMPD_declare_simd:
2303 case OMPD_declare_target:
2304 case OMPD_end_declare_target:
2305 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2305)
;
2306 case OMPD_unknown:
2307 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2307)
;
2308 }
2309}
2310
2311int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2312 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2313 getOpenMPCaptureRegions(CaptureRegions, DKind);
2314 return CaptureRegions.size();
2315}
2316
2317static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2318 Expr *CaptureExpr, bool WithInit,
2319 bool AsExpression) {
2320 assert(CaptureExpr)(static_cast <bool> (CaptureExpr) ? void (0) : __assert_fail
("CaptureExpr", "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2320, __extension__ __PRETTY_FUNCTION__))
;
2321 ASTContext &C = S.getASTContext();
2322 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2323 QualType Ty = Init->getType();
2324 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2325 if (S.getLangOpts().CPlusPlus)
2326 Ty = C.getLValueReferenceType(Ty);
2327 else {
2328 Ty = C.getPointerType(Ty);
2329 ExprResult Res =
2330 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2331 if (!Res.isUsable())
2332 return nullptr;
2333 Init = Res.get();
2334 }
2335 WithInit = true;
2336 }
2337 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2338 CaptureExpr->getLocStart());
2339 if (!WithInit)
2340 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2341 S.CurContext->addHiddenDecl(CED);
2342 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2343 return CED;
2344}
2345
2346static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2347 bool WithInit) {
2348 OMPCapturedExprDecl *CD;
2349 if (auto *VD = S.IsOpenMPCapturedDecl(D))
2350 CD = cast<OMPCapturedExprDecl>(VD);
2351 else
2352 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2353 /*AsExpression=*/false);
2354 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2355 CaptureExpr->getExprLoc());
2356}
2357
2358static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2359 if (!Ref) {
2360 auto *CD =
2361 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
2362 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
2363 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2364 CaptureExpr->getExprLoc());
2365 }
2366 ExprResult Res = Ref;
2367 if (!S.getLangOpts().CPlusPlus &&
2368 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2369 Ref->getType()->isPointerType())
2370 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2371 if (!Res.isUsable())
2372 return ExprError();
2373 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
2374}
2375
2376namespace {
2377// OpenMP directives parsed in this section are represented as a
2378// CapturedStatement with an associated statement. If a syntax error
2379// is detected during the parsing of the associated statement, the
2380// compiler must abort processing and close the CapturedStatement.
2381//
2382// Combined directives such as 'target parallel' have more than one
2383// nested CapturedStatements. This RAII ensures that we unwind out
2384// of all the nested CapturedStatements when an error is found.
2385class CaptureRegionUnwinderRAII {
2386private:
2387 Sema &S;
2388 bool &ErrorFound;
2389 OpenMPDirectiveKind DKind;
2390
2391public:
2392 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2393 OpenMPDirectiveKind DKind)
2394 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2395 ~CaptureRegionUnwinderRAII() {
2396 if (ErrorFound) {
2397 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2398 while (--ThisCaptureLevel >= 0)
2399 S.ActOnCapturedRegionError();
2400 }
2401 }
2402};
2403} // namespace
2404
2405StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2406 ArrayRef<OMPClause *> Clauses) {
2407 bool ErrorFound = false;
2408 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2409 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2410 if (!S.isUsable()) {
2411 ErrorFound = true;
2412 return StmtError();
2413 }
2414
2415 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2416 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2417 OMPOrderedClause *OC = nullptr;
2418 OMPScheduleClause *SC = nullptr;
2419 SmallVector<OMPLinearClause *, 4> LCs;
2420 SmallVector<OMPClauseWithPreInit *, 8> PICs;
2421 // This is required for proper codegen.
2422 for (auto *Clause : Clauses) {
2423 if (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2424 Clause->getClauseKind() == OMPC_in_reduction) {
2425 // Capture taskgroup task_reduction descriptors inside the tasking regions
2426 // with the corresponding in_reduction items.
2427 auto *IRC = cast<OMPInReductionClause>(Clause);
2428 for (auto *E : IRC->taskgroup_descriptors())
2429 if (E)
2430 MarkDeclarationsReferencedInExpr(E);
2431 }
2432 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2433 Clause->getClauseKind() == OMPC_copyprivate ||
2434 (getLangOpts().OpenMPUseTLS &&
2435 getASTContext().getTargetInfo().isTLSSupported() &&
2436 Clause->getClauseKind() == OMPC_copyin)) {
2437 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2438 // Mark all variables in private list clauses as used in inner region.
2439 for (auto *VarRef : Clause->children()) {
2440 if (auto *E = cast_or_null<Expr>(VarRef)) {
2441 MarkDeclarationsReferencedInExpr(E);
2442 }
2443 }
2444 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
2445 } else if (CaptureRegions.size() > 1 ||
2446 CaptureRegions.back() != OMPD_unknown) {
2447 if (auto *C = OMPClauseWithPreInit::get(Clause))
2448 PICs.push_back(C);
2449 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2450 if (auto *E = C->getPostUpdateExpr())
2451 MarkDeclarationsReferencedInExpr(E);
2452 }
2453 }
2454 if (Clause->getClauseKind() == OMPC_schedule)
2455 SC = cast<OMPScheduleClause>(Clause);
2456 else if (Clause->getClauseKind() == OMPC_ordered)
2457 OC = cast<OMPOrderedClause>(Clause);
2458 else if (Clause->getClauseKind() == OMPC_linear)
2459 LCs.push_back(cast<OMPLinearClause>(Clause));
2460 }
2461 // OpenMP, 2.7.1 Loop Construct, Restrictions
2462 // The nonmonotonic modifier cannot be specified if an ordered clause is
2463 // specified.
2464 if (SC &&
2465 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2466 SC->getSecondScheduleModifier() ==
2467 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2468 OC) {
2469 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2470 ? SC->getFirstScheduleModifierLoc()
2471 : SC->getSecondScheduleModifierLoc(),
2472 diag::err_omp_schedule_nonmonotonic_ordered)
2473 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2474 ErrorFound = true;
2475 }
2476 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2477 for (auto *C : LCs) {
2478 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2479 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2480 }
2481 ErrorFound = true;
2482 }
2483 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2484 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
2485 OC->getNumForLoops()) {
2486 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2487 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2488 ErrorFound = true;
2489 }
2490 if (ErrorFound) {
2491 return StmtError();
2492 }
2493 StmtResult SR = S;
2494 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2495 // Mark all variables in private list clauses as used in inner region.
2496 // Required for proper codegen of combined directives.
2497 // TODO: add processing for other clauses.
2498 if (ThisCaptureRegion != OMPD_unknown) {
2499 for (auto *C : PICs) {
2500 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2501 // Find the particular capture region for the clause if the
2502 // directive is a combined one with multiple capture regions.
2503 // If the directive is not a combined one, the capture region
2504 // associated with the clause is OMPD_unknown and is generated
2505 // only once.
2506 if (CaptureRegion == ThisCaptureRegion ||
2507 CaptureRegion == OMPD_unknown) {
2508 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2509 for (auto *D : DS->decls())
2510 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2511 }
2512 }
2513 }
2514 }
2515 SR = ActOnCapturedRegionEnd(SR.get());
2516 }
2517 return SR;
2518}
2519
2520static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2521 OpenMPDirectiveKind CancelRegion,
2522 SourceLocation StartLoc) {
2523 // CancelRegion is only needed for cancel and cancellation_point.
2524 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2525 return false;
2526
2527 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2528 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2529 return false;
2530
2531 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2532 << getOpenMPDirectiveName(CancelRegion);
2533 return true;
2534}
2535
2536static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2537 OpenMPDirectiveKind CurrentRegion,
2538 const DeclarationNameInfo &CurrentName,
2539 OpenMPDirectiveKind CancelRegion,
2540 SourceLocation StartLoc) {
2541 if (Stack->getCurScope()) {
2542 auto ParentRegion = Stack->getParentDirective();
2543 auto OffendingRegion = ParentRegion;
2544 bool NestingProhibited = false;
2545 bool CloseNesting = true;
2546 bool OrphanSeen = false;
2547 enum {
2548 NoRecommend,
2549 ShouldBeInParallelRegion,
2550 ShouldBeInOrderedRegion,
2551 ShouldBeInTargetRegion,
2552 ShouldBeInTeamsRegion
2553 } Recommend = NoRecommend;
2554 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2555 // OpenMP [2.16, Nesting of Regions]
2556 // OpenMP constructs may not be nested inside a simd region.
2557 // OpenMP [2.8.1,simd Construct, Restrictions]
2558 // An ordered construct with the simd clause is the only OpenMP
2559 // construct that can appear in the simd region.
2560 // Allowing a SIMD construct nested in another SIMD construct is an
2561 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2562 // message.
2563 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2564 ? diag::err_omp_prohibited_region_simd
2565 : diag::warn_omp_nesting_simd);
2566 return CurrentRegion != OMPD_simd;
2567 }
2568 if (ParentRegion == OMPD_atomic) {
2569 // OpenMP [2.16, Nesting of Regions]
2570 // OpenMP constructs may not be nested inside an atomic region.
2571 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2572 return true;
2573 }
2574 if (CurrentRegion == OMPD_section) {
2575 // OpenMP [2.7.2, sections Construct, Restrictions]
2576 // Orphaned section directives are prohibited. That is, the section
2577 // directives must appear within the sections construct and must not be
2578 // encountered elsewhere in the sections region.
2579 if (ParentRegion != OMPD_sections &&
2580 ParentRegion != OMPD_parallel_sections) {
2581 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2582 << (ParentRegion != OMPD_unknown)
2583 << getOpenMPDirectiveName(ParentRegion);
2584 return true;
2585 }
2586 return false;
2587 }
2588 // Allow some constructs (except teams) to be orphaned (they could be
2589 // used in functions, called from OpenMP regions with the required
2590 // preconditions).
2591 if (ParentRegion == OMPD_unknown &&
2592 !isOpenMPNestingTeamsDirective(CurrentRegion))
2593 return false;
2594 if (CurrentRegion == OMPD_cancellation_point ||
2595 CurrentRegion == OMPD_cancel) {
2596 // OpenMP [2.16, Nesting of Regions]
2597 // A cancellation point construct for which construct-type-clause is
2598 // taskgroup must be nested inside a task construct. A cancellation
2599 // point construct for which construct-type-clause is not taskgroup must
2600 // be closely nested inside an OpenMP construct that matches the type
2601 // specified in construct-type-clause.
2602 // A cancel construct for which construct-type-clause is taskgroup must be
2603 // nested inside a task construct. A cancel construct for which
2604 // construct-type-clause is not taskgroup must be closely nested inside an
2605 // OpenMP construct that matches the type specified in
2606 // construct-type-clause.
2607 NestingProhibited =
2608 !((CancelRegion == OMPD_parallel &&
2609 (ParentRegion == OMPD_parallel ||
2610 ParentRegion == OMPD_target_parallel)) ||
2611 (CancelRegion == OMPD_for &&
2612 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2613 ParentRegion == OMPD_target_parallel_for ||
2614 ParentRegion == OMPD_distribute_parallel_for ||
2615 ParentRegion == OMPD_teams_distribute_parallel_for ||
2616 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2617 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2618 (CancelRegion == OMPD_sections &&
2619 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2620 ParentRegion == OMPD_parallel_sections)));
2621 } else if (CurrentRegion == OMPD_master) {
2622 // OpenMP [2.16, Nesting of Regions]
2623 // A master region may not be closely nested inside a worksharing,
2624 // atomic, or explicit task region.
2625 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2626 isOpenMPTaskingDirective(ParentRegion);
2627 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2628 // OpenMP [2.16, Nesting of Regions]
2629 // A critical region may not be nested (closely or otherwise) inside a
2630 // critical region with the same name. Note that this restriction is not
2631 // sufficient to prevent deadlock.
2632 SourceLocation PreviousCriticalLoc;
2633 bool DeadLock = Stack->hasDirective(
2634 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2635 const DeclarationNameInfo &DNI,
2636 SourceLocation Loc) -> bool {
2637 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2638 PreviousCriticalLoc = Loc;
2639 return true;
2640 } else
2641 return false;
2642 },
2643 false /* skip top directive */);
2644 if (DeadLock) {
2645 SemaRef.Diag(StartLoc,
2646 diag::err_omp_prohibited_region_critical_same_name)
2647 << CurrentName.getName();
2648 if (PreviousCriticalLoc.isValid())
2649 SemaRef.Diag(PreviousCriticalLoc,
2650 diag::note_omp_previous_critical_region);
2651 return true;
2652 }
2653 } else if (CurrentRegion == OMPD_barrier) {
2654 // OpenMP [2.16, Nesting of Regions]
2655 // A barrier region may not be closely nested inside a worksharing,
2656 // explicit task, critical, ordered, atomic, or master region.
2657 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2658 isOpenMPTaskingDirective(ParentRegion) ||
2659 ParentRegion == OMPD_master ||
2660 ParentRegion == OMPD_critical ||
2661 ParentRegion == OMPD_ordered;
2662 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2663 !isOpenMPParallelDirective(CurrentRegion) &&
2664 !isOpenMPTeamsDirective(CurrentRegion)) {
2665 // OpenMP [2.16, Nesting of Regions]
2666 // A worksharing region may not be closely nested inside a worksharing,
2667 // explicit task, critical, ordered, atomic, or master region.
2668 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2669 isOpenMPTaskingDirective(ParentRegion) ||
2670 ParentRegion == OMPD_master ||
2671 ParentRegion == OMPD_critical ||
2672 ParentRegion == OMPD_ordered;
2673 Recommend = ShouldBeInParallelRegion;
2674 } else if (CurrentRegion == OMPD_ordered) {
2675 // OpenMP [2.16, Nesting of Regions]
2676 // An ordered region may not be closely nested inside a critical,
2677 // atomic, or explicit task region.
2678 // An ordered region must be closely nested inside a loop region (or
2679 // parallel loop region) with an ordered clause.
2680 // OpenMP [2.8.1,simd Construct, Restrictions]
2681 // An ordered construct with the simd clause is the only OpenMP construct
2682 // that can appear in the simd region.
2683 NestingProhibited = ParentRegion == OMPD_critical ||
2684 isOpenMPTaskingDirective(ParentRegion) ||
2685 !(isOpenMPSimdDirective(ParentRegion) ||
2686 Stack->isParentOrderedRegion());
2687 Recommend = ShouldBeInOrderedRegion;
2688 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2689 // OpenMP [2.16, Nesting of Regions]
2690 // If specified, a teams construct must be contained within a target
2691 // construct.
2692 NestingProhibited = ParentRegion != OMPD_target;
2693 OrphanSeen = ParentRegion == OMPD_unknown;
2694 Recommend = ShouldBeInTargetRegion;
2695 }
2696 if (!NestingProhibited &&
2697 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2698 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2699 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2700 // OpenMP [2.16, Nesting of Regions]
2701 // distribute, parallel, parallel sections, parallel workshare, and the
2702 // parallel loop and parallel loop SIMD constructs are the only OpenMP
2703 // constructs that can be closely nested in the teams region.
2704 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2705 !isOpenMPDistributeDirective(CurrentRegion);
2706 Recommend = ShouldBeInParallelRegion;
2707 }
2708 if (!NestingProhibited &&
2709 isOpenMPNestingDistributeDirective(CurrentRegion)) {
2710 // OpenMP 4.5 [2.17 Nesting of Regions]
2711 // The region associated with the distribute construct must be strictly
2712 // nested inside a teams region
2713 NestingProhibited =
2714 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2715 Recommend = ShouldBeInTeamsRegion;
2716 }
2717 if (!NestingProhibited &&
2718 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2719 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2720 // OpenMP 4.5 [2.17 Nesting of Regions]
2721 // If a target, target update, target data, target enter data, or
2722 // target exit data construct is encountered during execution of a
2723 // target region, the behavior is unspecified.
2724 NestingProhibited = Stack->hasDirective(
2725 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2726 SourceLocation) -> bool {
2727 if (isOpenMPTargetExecutionDirective(K)) {
2728 OffendingRegion = K;
2729 return true;
2730 } else
2731 return false;
2732 },
2733 false /* don't skip top directive */);
2734 CloseNesting = false;
2735 }
2736 if (NestingProhibited) {
2737 if (OrphanSeen) {
2738 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2739 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2740 } else {
2741 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2742 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2743 << Recommend << getOpenMPDirectiveName(CurrentRegion);
2744 }
2745 return true;
2746 }
2747 }
2748 return false;
2749}
2750
2751static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2752 ArrayRef<OMPClause *> Clauses,
2753 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2754 bool ErrorFound = false;
2755 unsigned NamedModifiersNumber = 0;
2756 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2757 OMPD_unknown + 1);
2758 SmallVector<SourceLocation, 4> NameModifierLoc;
2759 for (const auto *C : Clauses) {
2760 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2761 // At most one if clause without a directive-name-modifier can appear on
2762 // the directive.
2763 OpenMPDirectiveKind CurNM = IC->getNameModifier();
2764 if (FoundNameModifiers[CurNM]) {
2765 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2766 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2767 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2768 ErrorFound = true;
2769 } else if (CurNM != OMPD_unknown) {
2770 NameModifierLoc.push_back(IC->getNameModifierLoc());
2771 ++NamedModifiersNumber;
2772 }
2773 FoundNameModifiers[CurNM] = IC;
2774 if (CurNM == OMPD_unknown)
2775 continue;
2776 // Check if the specified name modifier is allowed for the current
2777 // directive.
2778 // At most one if clause with the particular directive-name-modifier can
2779 // appear on the directive.
2780 bool MatchFound = false;
2781 for (auto NM : AllowedNameModifiers) {
2782 if (CurNM == NM) {
2783 MatchFound = true;
2784 break;
2785 }
2786 }
2787 if (!MatchFound) {
2788 S.Diag(IC->getNameModifierLoc(),
2789 diag::err_omp_wrong_if_directive_name_modifier)
2790 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
2791 ErrorFound = true;
2792 }
2793 }
2794 }
2795 // If any if clause on the directive includes a directive-name-modifier then
2796 // all if clauses on the directive must include a directive-name-modifier.
2797 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2798 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2799 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2800 diag::err_omp_no_more_if_clause);
2801 } else {
2802 std::string Values;
2803 std::string Sep(", ");
2804 unsigned AllowedCnt = 0;
2805 unsigned TotalAllowedNum =
2806 AllowedNameModifiers.size() - NamedModifiersNumber;
2807 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2808 ++Cnt) {
2809 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2810 if (!FoundNameModifiers[NM]) {
2811 Values += "'";
2812 Values += getOpenMPDirectiveName(NM);
2813 Values += "'";
2814 if (AllowedCnt + 2 == TotalAllowedNum)
2815 Values += " or ";
2816 else if (AllowedCnt + 1 != TotalAllowedNum)
2817 Values += Sep;
2818 ++AllowedCnt;
2819 }
2820 }
2821 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2822 diag::err_omp_unnamed_if_clause)
2823 << (TotalAllowedNum > 1) << Values;
2824 }
2825 for (auto Loc : NameModifierLoc) {
2826 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2827 }
2828 ErrorFound = true;
2829 }
2830 return ErrorFound;
2831}
2832
2833StmtResult Sema::ActOnOpenMPExecutableDirective(
2834 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2835 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2836 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2837 StmtResult Res = StmtError();
2838 // First check CancelRegion which is then used in checkNestingOfRegions.
2839 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2840 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
2841 StartLoc))
2842 return StmtError();
2843
2844 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2845 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2846 bool ErrorFound = false;
2847 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2848 if (AStmt && !CurContext->isDependentContext()) {
2849 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2849, __extension__ __PRETTY_FUNCTION__))
;
2850
2851 // Check default data sharing attributes for referenced variables.
2852 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
2853 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2854 Stmt *S = AStmt;
2855 while (--ThisCaptureLevel >= 0)
2856 S = cast<CapturedStmt>(S)->getCapturedStmt();
2857 DSAChecker.Visit(S);
2858 if (DSAChecker.isErrorFound())
2859 return StmtError();
2860 // Generate list of implicitly defined firstprivate variables.
2861 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2862
2863 SmallVector<Expr *, 4> ImplicitFirstprivates(
2864 DSAChecker.getImplicitFirstprivate().begin(),
2865 DSAChecker.getImplicitFirstprivate().end());
2866 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2867 DSAChecker.getImplicitMap().end());
2868 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2869 for (auto *C : Clauses) {
2870 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2871 for (auto *E : IRC->taskgroup_descriptors())
2872 if (E)
2873 ImplicitFirstprivates.emplace_back(E);
2874 }
2875 }
2876 if (!ImplicitFirstprivates.empty()) {
2877 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2878 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2879 SourceLocation())) {
2880 ClausesWithImplicit.push_back(Implicit);
2881 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2882 ImplicitFirstprivates.size();
2883 } else
2884 ErrorFound = true;
2885 }
2886 if (!ImplicitMaps.empty()) {
2887 if (OMPClause *Implicit = ActOnOpenMPMapClause(
2888 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2889 SourceLocation(), SourceLocation(), ImplicitMaps,
2890 SourceLocation(), SourceLocation(), SourceLocation())) {
2891 ClausesWithImplicit.emplace_back(Implicit);
2892 ErrorFound |=
2893 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2894 } else
2895 ErrorFound = true;
2896 }
2897 }
2898
2899 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2900 switch (Kind) {
2901 case OMPD_parallel:
2902 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2903 EndLoc);
2904 AllowedNameModifiers.push_back(OMPD_parallel);
2905 break;
2906 case OMPD_simd:
2907 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2908 VarsWithInheritedDSA);
2909 break;
2910 case OMPD_for:
2911 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2912 VarsWithInheritedDSA);
2913 break;
2914 case OMPD_for_simd:
2915 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2916 EndLoc, VarsWithInheritedDSA);
2917 break;
2918 case OMPD_sections:
2919 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2920 EndLoc);
2921 break;
2922 case OMPD_section:
2923 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2924, __extension__ __PRETTY_FUNCTION__))
2924 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2924, __extension__ __PRETTY_FUNCTION__))
;
2925 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2926 break;
2927 case OMPD_single:
2928 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2929 EndLoc);
2930 break;
2931 case OMPD_master:
2932 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2933, __extension__ __PRETTY_FUNCTION__))
2933 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2933, __extension__ __PRETTY_FUNCTION__))
;
2934 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2935 break;
2936 case OMPD_critical:
2937 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2938 StartLoc, EndLoc);
2939 break;
2940 case OMPD_parallel_for:
2941 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2942 EndLoc, VarsWithInheritedDSA);
2943 AllowedNameModifiers.push_back(OMPD_parallel);
2944 break;
2945 case OMPD_parallel_for_simd:
2946 Res = ActOnOpenMPParallelForSimdDirective(
2947 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2948 AllowedNameModifiers.push_back(OMPD_parallel);
2949 break;
2950 case OMPD_parallel_sections:
2951 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2952 StartLoc, EndLoc);
2953 AllowedNameModifiers.push_back(OMPD_parallel);
2954 break;
2955 case OMPD_task:
2956 Res =
2957 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2958 AllowedNameModifiers.push_back(OMPD_task);
2959 break;
2960 case OMPD_taskyield:
2961 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2962, __extension__ __PRETTY_FUNCTION__))
2962 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2962, __extension__ __PRETTY_FUNCTION__))
;
2963 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2964, __extension__ __PRETTY_FUNCTION__))
2964 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2964, __extension__ __PRETTY_FUNCTION__))
;
2965 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2966 break;
2967 case OMPD_barrier:
2968 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2969, __extension__ __PRETTY_FUNCTION__))
2969 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2969, __extension__ __PRETTY_FUNCTION__))
;
2970 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2971, __extension__ __PRETTY_FUNCTION__))
2971 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2971, __extension__ __PRETTY_FUNCTION__))
;
2972 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2973 break;
2974 case OMPD_taskwait:
2975 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2976, __extension__ __PRETTY_FUNCTION__))
2976 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2976, __extension__ __PRETTY_FUNCTION__))
;
2977 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2978, __extension__ __PRETTY_FUNCTION__))
2978 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2978, __extension__ __PRETTY_FUNCTION__))
;
2979 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2980 break;
2981 case OMPD_taskgroup:
2982 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2983 EndLoc);
2984 break;
2985 case OMPD_flush:
2986 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2987, __extension__ __PRETTY_FUNCTION__))
2987 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2987, __extension__ __PRETTY_FUNCTION__))
;
2988 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2989 break;
2990 case OMPD_ordered:
2991 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
2992 EndLoc);
2993 break;
2994 case OMPD_atomic:
2995 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
2996 EndLoc);
2997 break;
2998 case OMPD_teams:
2999 Res =
3000 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3001 break;
3002 case OMPD_target:
3003 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3004 EndLoc);
3005 AllowedNameModifiers.push_back(OMPD_target);
3006 break;
3007 case OMPD_target_parallel:
3008 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3009 StartLoc, EndLoc);
3010 AllowedNameModifiers.push_back(OMPD_target);
3011 AllowedNameModifiers.push_back(OMPD_parallel);
3012 break;
3013 case OMPD_target_parallel_for:
3014 Res = ActOnOpenMPTargetParallelForDirective(
3015 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3016 AllowedNameModifiers.push_back(OMPD_target);
3017 AllowedNameModifiers.push_back(OMPD_parallel);
3018 break;
3019 case OMPD_cancellation_point:
3020 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3021, __extension__ __PRETTY_FUNCTION__))
3021 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3021, __extension__ __PRETTY_FUNCTION__))
;
3022 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3023, __extension__ __PRETTY_FUNCTION__))
3023 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3023, __extension__ __PRETTY_FUNCTION__))
;
3024 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3025 break;
3026 case OMPD_cancel:
3027 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3028, __extension__ __PRETTY_FUNCTION__))
3028 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3028, __extension__ __PRETTY_FUNCTION__))
;
3029 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3030 CancelRegion);
3031 AllowedNameModifiers.push_back(OMPD_cancel);
3032 break;
3033 case OMPD_target_data:
3034 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3035 EndLoc);
3036 AllowedNameModifiers.push_back(OMPD_target_data);
3037 break;
3038 case OMPD_target_enter_data:
3039 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3040 EndLoc, AStmt);
3041 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3042 break;
3043 case OMPD_target_exit_data:
3044 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3045 EndLoc, AStmt);
3046 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3047 break;
3048 case OMPD_taskloop:
3049 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3050 EndLoc, VarsWithInheritedDSA);
3051 AllowedNameModifiers.push_back(OMPD_taskloop);
3052 break;
3053 case OMPD_taskloop_simd:
3054 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3055 EndLoc, VarsWithInheritedDSA);
3056 AllowedNameModifiers.push_back(OMPD_taskloop);
3057 break;
3058 case OMPD_distribute:
3059 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3060 EndLoc, VarsWithInheritedDSA);
3061 break;
3062 case OMPD_target_update:
3063 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3064 EndLoc, AStmt);
3065 AllowedNameModifiers.push_back(OMPD_target_update);
3066 break;
3067 case OMPD_distribute_parallel_for:
3068 Res = ActOnOpenMPDistributeParallelForDirective(
3069 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3070 AllowedNameModifiers.push_back(OMPD_parallel);
3071 break;
3072 case OMPD_distribute_parallel_for_simd:
3073 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3074 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3075 AllowedNameModifiers.push_back(OMPD_parallel);
3076 break;
3077 case OMPD_distribute_simd:
3078 Res = ActOnOpenMPDistributeSimdDirective(
3079 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3080 break;
3081 case OMPD_target_parallel_for_simd:
3082 Res = ActOnOpenMPTargetParallelForSimdDirective(
3083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084 AllowedNameModifiers.push_back(OMPD_target);
3085 AllowedNameModifiers.push_back(OMPD_parallel);
3086 break;
3087 case OMPD_target_simd:
3088 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3089 EndLoc, VarsWithInheritedDSA);
3090 AllowedNameModifiers.push_back(OMPD_target);
3091 break;
3092 case OMPD_teams_distribute:
3093 Res = ActOnOpenMPTeamsDistributeDirective(
3094 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3095 break;
3096 case OMPD_teams_distribute_simd:
3097 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3098 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3099 break;
3100 case OMPD_teams_distribute_parallel_for_simd:
3101 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3102 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3103 AllowedNameModifiers.push_back(OMPD_parallel);
3104 break;
3105 case OMPD_teams_distribute_parallel_for:
3106 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3107 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3108 AllowedNameModifiers.push_back(OMPD_parallel);
3109 break;
3110 case OMPD_target_teams:
3111 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3112 EndLoc);
3113 AllowedNameModifiers.push_back(OMPD_target);
3114 break;
3115 case OMPD_target_teams_distribute:
3116 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3117 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3118 AllowedNameModifiers.push_back(OMPD_target);
3119 break;
3120 case OMPD_target_teams_distribute_parallel_for:
3121 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3122 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3123 AllowedNameModifiers.push_back(OMPD_target);
3124 AllowedNameModifiers.push_back(OMPD_parallel);
3125 break;
3126 case OMPD_target_teams_distribute_parallel_for_simd:
3127 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3128 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3129 AllowedNameModifiers.push_back(OMPD_target);
3130 AllowedNameModifiers.push_back(OMPD_parallel);
3131 break;
3132 case OMPD_target_teams_distribute_simd:
3133 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3134 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3135 AllowedNameModifiers.push_back(OMPD_target);
3136 break;
3137 case OMPD_declare_target:
3138 case OMPD_end_declare_target:
3139 case OMPD_threadprivate:
3140 case OMPD_declare_reduction:
3141 case OMPD_declare_simd:
3142 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3142)
;
3143 case OMPD_unknown:
3144 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3144)
;
3145 }
3146
3147 for (auto P : VarsWithInheritedDSA) {
3148 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3149 << P.first << P.second->getSourceRange();
3150 }
3151 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3152
3153 if (!AllowedNameModifiers.empty())
3154 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3155 ErrorFound;
3156
3157 if (ErrorFound)
3158 return StmtError();
3159 return Res;
3160}
3161
3162Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3163 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3164 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3165 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3166 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3167 assert(Aligneds.size() == Alignments.size())(static_cast <bool> (Aligneds.size() == Alignments.size
()) ? void (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3167, __extension__ __PRETTY_FUNCTION__))
;
3168 assert(Linears.size() == LinModifiers.size())(static_cast <bool> (Linears.size() == LinModifiers.size
()) ? void (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3168, __extension__ __PRETTY_FUNCTION__))
;
3169 assert(Linears.size() == Steps.size())(static_cast <bool> (Linears.size() == Steps.size()) ? void
(0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3169, __extension__ __PRETTY_FUNCTION__))
;
3170 if (!DG || DG.get().isNull())
3171 return DeclGroupPtrTy();
3172
3173 if (!DG.get().isSingleDecl()) {
3174 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3175 return DG;
3176 }
3177 auto *ADecl = DG.get().getSingleDecl();
3178 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3179 ADecl = FTD->getTemplatedDecl();
3180
3181 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3182 if (!FD) {
3183 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3184 return DeclGroupPtrTy();
3185 }
3186
3187 // OpenMP [2.8.2, declare simd construct, Description]
3188 // The parameter of the simdlen clause must be a constant positive integer
3189 // expression.
3190 ExprResult SL;
3191 if (Simdlen)
3192 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3193 // OpenMP [2.8.2, declare simd construct, Description]
3194 // The special this pointer can be used as if was one of the arguments to the
3195 // function in any of the linear, aligned, or uniform clauses.
3196 // The uniform clause declares one or more arguments to have an invariant
3197 // value for all concurrent invocations of the function in the execution of a
3198 // single SIMD loop.
3199 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3200 Expr *UniformedLinearThis = nullptr;
3201 for (auto *E : Uniforms) {
3202 E = E->IgnoreParenImpCasts();
3203 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3204 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3205 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3206 FD->getParamDecl(PVD->getFunctionScopeIndex())
3207 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3208 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3209 continue;
3210 }
3211 if (isa<CXXThisExpr>(E)) {
3212 UniformedLinearThis = E;
3213 continue;
3214 }
3215 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3216 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3217 }
3218 // OpenMP [2.8.2, declare simd construct, Description]
3219 // The aligned clause declares that the object to which each list item points
3220 // is aligned to the number of bytes expressed in the optional parameter of
3221 // the aligned clause.
3222 // The special this pointer can be used as if was one of the arguments to the
3223 // function in any of the linear, aligned, or uniform clauses.
3224 // The type of list items appearing in the aligned clause must be array,
3225 // pointer, reference to array, or reference to pointer.
3226 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3227 Expr *AlignedThis = nullptr;
3228 for (auto *E : Aligneds) {
3229 E = E->IgnoreParenImpCasts();
3230 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3231 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3232 auto *CanonPVD = PVD->getCanonicalDecl();
3233 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3234 FD->getParamDecl(PVD->getFunctionScopeIndex())
3235 ->getCanonicalDecl() == CanonPVD) {
3236 // OpenMP [2.8.1, simd construct, Restrictions]
3237 // A list-item cannot appear in more than one aligned clause.
3238 if (AlignedArgs.count(CanonPVD) > 0) {
3239 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3240 << 1 << E->getSourceRange();
3241 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3242 diag::note_omp_explicit_dsa)
3243 << getOpenMPClauseName(OMPC_aligned);
3244 continue;
3245 }
3246 AlignedArgs[CanonPVD] = E;
3247 QualType QTy = PVD->getType()
3248 .getNonReferenceType()
3249 .getUnqualifiedType()
3250 .getCanonicalType();
3251 const Type *Ty = QTy.getTypePtrOrNull();
3252 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3253 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3254 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3255 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3256 }
3257 continue;
3258 }
3259 }
3260 if (isa<CXXThisExpr>(E)) {
3261 if (AlignedThis) {
3262 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3263 << 2 << E->getSourceRange();
3264 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3265 << getOpenMPClauseName(OMPC_aligned);
3266 }
3267 AlignedThis = E;
3268 continue;
3269 }
3270 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3271 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3272 }
3273 // The optional parameter of the aligned clause, alignment, must be a constant
3274 // positive integer expression. If no optional parameter is specified,
3275 // implementation-defined default alignments for SIMD instructions on the
3276 // target platforms are assumed.
3277 SmallVector<Expr *, 4> NewAligns;
3278 for (auto *E : Alignments) {
3279 ExprResult Align;
3280 if (E)
3281 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3282 NewAligns.push_back(Align.get());
3283 }
3284 // OpenMP [2.8.2, declare simd construct, Description]
3285 // The linear clause declares one or more list items to be private to a SIMD
3286 // lane and to have a linear relationship with respect to the iteration space
3287 // of a loop.
3288 // The special this pointer can be used as if was one of the arguments to the
3289 // function in any of the linear, aligned, or uniform clauses.
3290 // When a linear-step expression is specified in a linear clause it must be
3291 // either a constant integer expression or an integer-typed parameter that is
3292 // specified in a uniform clause on the directive.
3293 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3294 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3295 auto MI = LinModifiers.begin();
3296 for (auto *E : Linears) {
3297 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3298 ++MI;
3299 E = E->IgnoreParenImpCasts();
3300 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3301 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3302 auto *CanonPVD = PVD->getCanonicalDecl();
3303 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3304 FD->getParamDecl(PVD->getFunctionScopeIndex())
3305 ->getCanonicalDecl() == CanonPVD) {
3306 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3307 // A list-item cannot appear in more than one linear clause.
3308 if (LinearArgs.count(CanonPVD) > 0) {
3309 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3310 << getOpenMPClauseName(OMPC_linear)
3311 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3312 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3313 diag::note_omp_explicit_dsa)
3314 << getOpenMPClauseName(OMPC_linear);
3315 continue;
3316 }
3317 // Each argument can appear in at most one uniform or linear clause.
3318 if (UniformedArgs.count(CanonPVD) > 0) {
3319 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3320 << getOpenMPClauseName(OMPC_linear)
3321 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3322 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3323 diag::note_omp_explicit_dsa)
3324 << getOpenMPClauseName(OMPC_uniform);
3325 continue;
3326 }
3327 LinearArgs[CanonPVD] = E;
3328 if (E->isValueDependent() || E->isTypeDependent() ||
3329 E->isInstantiationDependent() ||
3330 E->containsUnexpandedParameterPack())
3331 continue;
3332 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3333 PVD->getOriginalType());
3334 continue;
3335 }
3336 }
3337 if (isa<CXXThisExpr>(E)) {
3338 if (UniformedLinearThis) {
3339 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3340 << getOpenMPClauseName(OMPC_linear)
3341 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3342 << E->getSourceRange();
3343 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3344 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3345 : OMPC_linear);
3346 continue;
3347 }
3348 UniformedLinearThis = E;
3349 if (E->isValueDependent() || E->isTypeDependent() ||
3350 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3351 continue;
3352 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3353 E->getType());
3354 continue;
3355 }
3356 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3357 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3358 }
3359 Expr *Step = nullptr;
3360 Expr *NewStep = nullptr;
3361 SmallVector<Expr *, 4> NewSteps;
3362 for (auto *E : Steps) {
3363 // Skip the same step expression, it was checked already.
3364 if (Step == E || !E) {
3365 NewSteps.push_back(E ? NewStep : nullptr);
3366 continue;
3367 }
3368 Step = E;
3369 if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3370 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3371 auto *CanonPVD = PVD->getCanonicalDecl();
3372 if (UniformedArgs.count(CanonPVD) == 0) {
3373 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3374 << Step->getSourceRange();
3375 } else if (E->isValueDependent() || E->isTypeDependent() ||
3376 E->isInstantiationDependent() ||
3377 E->containsUnexpandedParameterPack() ||
3378 CanonPVD->getType()->hasIntegerRepresentation())
3379 NewSteps.push_back(Step);
3380 else {
3381 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3382 << Step->getSourceRange();
3383 }
3384 continue;
3385 }
3386 NewStep = Step;
3387 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3388 !Step->isInstantiationDependent() &&
3389 !Step->containsUnexpandedParameterPack()) {
3390 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3391 .get();
3392 if (NewStep)
3393 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3394 }
3395 NewSteps.push_back(NewStep);
3396 }
3397 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3398 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3399 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3400 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3401 const_cast<Expr **>(Linears.data()), Linears.size(),
3402 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3403 NewSteps.data(), NewSteps.size(), SR);
3404 ADecl->addAttr(NewAttr);
3405 return ConvertDeclToDeclGroup(ADecl);
3406}
3407
3408StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3409 Stmt *AStmt,
3410 SourceLocation StartLoc,
3411 SourceLocation EndLoc) {
3412 if (!AStmt)
3413 return StmtError();
3414
3415 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3416 // 1.2.2 OpenMP Language Terminology
3417 // Structured block - An executable statement with a single entry at the
3418 // top and a single exit at the bottom.
3419 // The point of exit cannot be a branch out of the structured block.
3420 // longjmp() and throw() must not violate the entry/exit criteria.
3421 CS->getCapturedDecl()->setNothrow();
3422
3423 getCurFunction()->setHasBranchProtectedScope();
3424
3425 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3426 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
3427}
3428
3429namespace {
3430/// \brief Helper class for checking canonical form of the OpenMP loops and
3431/// extracting iteration space of each loop in the loop nest, that will be used
3432/// for IR generation.
3433class OpenMPIterationSpaceChecker {
3434 /// \brief Reference to Sema.
3435 Sema &SemaRef;
3436 /// \brief A location for diagnostics (when there is no some better location).
3437 SourceLocation DefaultLoc;
3438 /// \brief A location for diagnostics (when increment is not compatible).
3439 SourceLocation ConditionLoc;
3440 /// \brief A source location for referring to loop init later.
3441 SourceRange InitSrcRange;
3442 /// \brief A source location for referring to condition later.
3443 SourceRange ConditionSrcRange;
3444 /// \brief A source location for referring to increment later.
3445 SourceRange IncrementSrcRange;
3446 /// \brief Loop variable.
3447 ValueDecl *LCDecl = nullptr;
10
Null pointer value stored to 'ISC.LCDecl'
3448 /// \brief Reference to loop variable.
3449 Expr *LCRef = nullptr;
3450 /// \brief Lower bound (initializer for the var).
3451 Expr *LB = nullptr;
3452 /// \brief Upper bound.
3453 Expr *UB = nullptr;
3454 /// \brief Loop step (increment).
3455 Expr *Step = nullptr;
3456 /// \brief This flag is true when condition is one of:
3457 /// Var < UB
3458 /// Var <= UB
3459 /// UB > Var
3460 /// UB >= Var
3461 bool TestIsLessOp = false;
3462 /// \brief This flag is true when condition is strict ( < or > ).
3463 bool TestIsStrictOp = false;
3464 /// \brief This flag is true when step is subtracted on each iteration.
3465 bool SubtractStep = false;
3466
3467public:
3468 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3469 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3470 /// \brief Check init-expr for canonical loop form and save loop counter
3471 /// variable - #Var and its initialization value - #LB.
3472 bool CheckInit(Stmt *S, bool EmitDiags = true);
3473 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3474 /// for less/greater and for strict/non-strict comparison.
3475 bool CheckCond(Expr *S);
3476 /// \brief Check incr-expr for canonical loop form and return true if it
3477 /// does not conform, otherwise save loop step (#Step).
3478 bool CheckInc(Expr *S);
3479 /// \brief Return the loop counter variable.
3480 ValueDecl *GetLoopDecl() const { return LCDecl; }
3481 /// \brief Return the reference expression to loop counter variable.
3482 Expr *GetLoopDeclRefExpr() const { return LCRef; }
3483 /// \brief Source range of the loop init.
3484 SourceRange GetInitSrcRange() const { return InitSrcRange; }
3485 /// \brief Source range of the loop condition.
3486 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3487 /// \brief Source range of the loop increment.
3488 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3489 /// \brief True if the step should be subtracted.
3490 bool ShouldSubtractStep() const { return SubtractStep; }
3491 /// \brief Build the expression to calculate the number of iterations.
3492 Expr *
3493 BuildNumIterations(Scope *S, const bool LimitedType,
3494 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3495 /// \brief Build the precondition expression for the loops.
3496 Expr *BuildPreCond(Scope *S, Expr *Cond,
3497 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3498 /// \brief Build reference expression to the counter be used for codegen.
3499 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3500 DSAStackTy &DSA) const;
3501 /// \brief Build reference expression to the private counter be used for
3502 /// codegen.
3503 Expr *BuildPrivateCounterVar() const;
3504 /// \brief Build initialization of the counter be used for codegen.
3505 Expr *BuildCounterInit() const;
3506 /// \brief Build step of the counter be used for codegen.
3507 Expr *BuildCounterStep() const;
3508 /// \brief Return true if any expression is dependent.
3509 bool Dependent() const;
3510
3511private:
3512 /// \brief Check the right-hand side of an assignment in the increment
3513 /// expression.
3514 bool CheckIncRHS(Expr *RHS);
3515 /// \brief Helper to set loop counter variable and its initializer.
3516 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3517 /// \brief Helper to set upper bound.
3518 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3519 SourceLocation SL);
3520 /// \brief Helper to set loop increment.
3521 bool SetStep(Expr *NewStep, bool Subtract);
3522};
3523
3524bool OpenMPIterationSpaceChecker::Dependent() const {
3525 if (!LCDecl) {
3526 assert(!LB && !UB && !Step)(static_cast <bool> (!LB && !UB && !Step
) ? void (0) : __assert_fail ("!LB && !UB && !Step"
, "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3526, __extension__ __PRETTY_FUNCTION__))
;
3527 return false;
3528 }
3529 return LCDecl->getType()->isDependentType() ||
3530 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3531 (Step && Step->isValueDependent());
3532}
3533
3534bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3535 Expr *NewLCRefExpr,
3536 Expr *NewLB) {
3537 // State consistency checking to ensure correct usage.
3538 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3539, __extension__ __PRETTY_FUNCTION__))
3539 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3539, __extension__ __PRETTY_FUNCTION__))
;
3540 if (!NewLCDecl || !NewLB)
3541 return true;
3542 LCDecl = getCanonicalDecl(NewLCDecl);
3543 LCRef = NewLCRefExpr;
3544 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3545 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3546 if ((Ctor->isCopyOrMoveConstructor() ||
3547 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3548 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3549 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3550 LB = NewLB;
3551 return false;
3552}
3553
3554bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3555 SourceRange SR, SourceLocation SL) {
3556 // State consistency checking to ensure correct usage.
3557 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3558, __extension__ __PRETTY_FUNCTION__))
3558 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3558, __extension__ __PRETTY_FUNCTION__))
;
3559 if (!NewUB)
3560 return true;
3561 UB = NewUB;
3562 TestIsLessOp = LessOp;
3563 TestIsStrictOp = StrictOp;
3564 ConditionSrcRange = SR;
3565 ConditionLoc = SL;
3566 return false;
3567}
3568
3569bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3570 // State consistency checking to ensure correct usage.
3571 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3571, __extension__ __PRETTY_FUNCTION__))
;
3572 if (!NewStep)
3573 return true;
3574 if (!NewStep->isValueDependent()) {
3575 // Check that the step is integer expression.
3576 SourceLocation StepLoc = NewStep->getLocStart();
3577 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3578 StepLoc, getExprAsWritten(NewStep));
3579 if (Val.isInvalid())
3580 return true;
3581 NewStep = Val.get();
3582
3583 // OpenMP [2.6, Canonical Loop Form, Restrictions]
3584 // If test-expr is of form var relational-op b and relational-op is < or
3585 // <= then incr-expr must cause var to increase on each iteration of the
3586 // loop. If test-expr is of form var relational-op b and relational-op is
3587 // > or >= then incr-expr must cause var to decrease on each iteration of
3588 // the loop.
3589 // If test-expr is of form b relational-op var and relational-op is < or
3590 // <= then incr-expr must cause var to decrease on each iteration of the
3591 // loop. If test-expr is of form b relational-op var and relational-op is
3592 // > or >= then incr-expr must cause var to increase on each iteration of
3593 // the loop.
3594 llvm::APSInt Result;
3595 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3596 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3597 bool IsConstNeg =
3598 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3599 bool IsConstPos =
3600 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3601 bool IsConstZero = IsConstant && !Result.getBoolValue();
3602 if (UB && (IsConstZero ||
3603 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3604 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3605 SemaRef.Diag(NewStep->getExprLoc(),
3606 diag::err_omp_loop_incr_not_compatible)
3607 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3608 SemaRef.Diag(ConditionLoc,
3609 diag::note_omp_loop_cond_requres_compatible_incr)
3610 << TestIsLessOp << ConditionSrcRange;
3611 return true;
3612 }
3613 if (TestIsLessOp == Subtract) {
3614 NewStep =
3615 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3616 .get();
3617 Subtract = !Subtract;
3618 }
3619 }
3620
3621 Step = NewStep;
3622 SubtractStep = Subtract;
3623 return false;
3624}
3625
3626bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3627 // Check init-expr for canonical loop form and save loop counter
3628 // variable - #Var and its initialization value - #LB.
3629 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3630 // var = lb
3631 // integer-type var = lb
3632 // random-access-iterator-type var = lb
3633 // pointer-type var = lb
3634 //
3635 if (!S) {
3636 if (EmitDiags) {
3637 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3638 }
3639 return true;
3640 }
3641 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3642 if (!ExprTemp->cleanupsHaveSideEffects())
3643 S = ExprTemp->getSubExpr();
3644
3645 InitSrcRange = S->getSourceRange();
3646 if (Expr *E = dyn_cast<Expr>(S))
3647 S = E->IgnoreParens();
3648 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3649 if (BO->getOpcode() == BO_Assign) {
3650 auto *LHS = BO->getLHS()->IgnoreParens();
3651 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3652 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3653 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3654 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3655 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3656 }
3657 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3658 if (ME->isArrow() &&
3659 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3660 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3661 }
3662 }
3663 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3664 if (DS->isSingleDecl()) {
3665 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3666 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3667 // Accept non-canonical init form here but emit ext. warning.
3668 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3669 SemaRef.Diag(S->getLocStart(),
3670 diag::ext_omp_loop_not_canonical_init)
3671 << S->getSourceRange();
3672 return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3673 }
3674 }
3675 }
3676 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3677 if (CE->getOperator() == OO_Equal) {
3678 auto *LHS = CE->getArg(0);
3679 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3680 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3681 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3682 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3683 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3684 }
3685 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3686 if (ME->isArrow() &&
3687 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3688 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3689 }
3690 }
3691 }
3692
3693 if (Dependent() || SemaRef.CurContext->isDependentContext())
3694 return false;
3695 if (EmitDiags) {
3696 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3697 << S->getSourceRange();
3698 }
3699 return true;
3700}
3701
3702/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3703/// variable (which may be the loop variable) if possible.
3704static const ValueDecl *GetInitLCDecl(Expr *E) {
3705 if (!E)
3706 return nullptr;
3707 E = getExprAsWritten(E);
3708 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3709 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3710 if ((Ctor->isCopyOrMoveConstructor() ||
3711 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3712 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3713 E = CE->getArg(0)->IgnoreParenImpCasts();
3714 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3715 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3716 return getCanonicalDecl(VD);
3717 }
3718 if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3719 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3720 return getCanonicalDecl(ME->getMemberDecl());
3721 return nullptr;
3722}
3723
3724bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3725 // Check test-expr for canonical form, save upper-bound UB, flags for
3726 // less/greater and for strict/non-strict comparison.
3727 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3728 // var relational-op b
3729 // b relational-op var
3730 //
3731 if (!S) {
3732 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3733 return true;
3734 }
3735 S = getExprAsWritten(S);
3736 SourceLocation CondLoc = S->getLocStart();
3737 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3738 if (BO->isRelationalOp()) {
3739 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3740 return SetUB(BO->getRHS(),
3741 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3742 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3743 BO->getSourceRange(), BO->getOperatorLoc());
3744 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3745 return SetUB(BO->getLHS(),
3746 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3747 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3748 BO->getSourceRange(), BO->getOperatorLoc());
3749 }
3750 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3751 if (CE->getNumArgs() == 2) {
3752 auto Op = CE->getOperator();
3753 switch (Op) {
3754 case OO_Greater:
3755 case OO_GreaterEqual:
3756 case OO_Less:
3757 case OO_LessEqual:
3758 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3759 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3760 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3761 CE->getOperatorLoc());
3762 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3763 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3764 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3765 CE->getOperatorLoc());
3766 break;
3767 default:
3768 break;
3769 }
3770 }
3771 }
3772 if (Dependent() || SemaRef.CurContext->isDependentContext())
3773 return false;
3774 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3775 << S->getSourceRange() << LCDecl;
3776 return true;
3777}
3778
3779bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3780 // RHS of canonical loop form increment can be:
3781 // var + incr
3782 // incr + var
3783 // var - incr
3784 //
3785 RHS = RHS->IgnoreParenImpCasts();
3786 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3787 if (BO->isAdditiveOp()) {
3788 bool IsAdd = BO->getOpcode() == BO_Add;
3789 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3790 return SetStep(BO->getRHS(), !IsAdd);
3791 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3792 return SetStep(BO->getLHS(), false);
3793 }
3794 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3795 bool IsAdd = CE->getOperator() == OO_Plus;
3796 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3797 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3798 return SetStep(CE->getArg(1), !IsAdd);
3799 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3800 return SetStep(CE->getArg(0), false);
3801 }
3802 }
3803 if (Dependent() || SemaRef.CurContext->isDependentContext())
3804 return false;
3805 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3806 << RHS->getSourceRange() << LCDecl;
3807 return true;
3808}
3809
3810bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3811 // Check incr-expr for canonical loop form and return true if it
3812 // does not conform.
3813 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3814 // ++var
3815 // var++
3816 // --var
3817 // var--
3818 // var += incr
3819 // var -= incr
3820 // var = var + incr
3821 // var = incr + var
3822 // var = var - incr
3823 //
3824 if (!S) {
3825 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3826 return true;
3827 }
3828 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3829 if (!ExprTemp->cleanupsHaveSideEffects())
3830 S = ExprTemp->getSubExpr();
3831
3832 IncrementSrcRange = S->getSourceRange();
3833 S = S->IgnoreParens();
3834 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3835 if (UO->isIncrementDecrementOp() &&
3836 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3837 return SetStep(SemaRef
3838 .ActOnIntegerConstant(UO->getLocStart(),
3839 (UO->isDecrementOp() ? -1 : 1))
3840 .get(),
3841 false);
3842 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3843 switch (BO->getOpcode()) {
3844 case BO_AddAssign:
3845 case BO_SubAssign:
3846 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3847 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3848 break;
3849 case BO_Assign:
3850 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3851 return CheckIncRHS(BO->getRHS());
3852 break;
3853 default:
3854 break;
3855 }
3856 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3857 switch (CE->getOperator()) {
3858 case OO_PlusPlus:
3859 case OO_MinusMinus:
3860 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3861 return SetStep(SemaRef
3862 .ActOnIntegerConstant(
3863 CE->getLocStart(),
3864 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3865 .get(),
3866 false);
3867 break;
3868 case OO_PlusEqual:
3869 case OO_MinusEqual:
3870 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3871 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3872 break;
3873 case OO_Equal:
3874 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3875 return CheckIncRHS(CE->getArg(1));
3876 break;
3877 default:
3878 break;
3879 }
3880 }
3881 if (Dependent() || SemaRef.CurContext->isDependentContext())
3882 return false;
3883 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3884 << S->getSourceRange() << LCDecl;
3885 return true;
3886}
3887
3888static ExprResult
3889tryBuildCapture(Sema &SemaRef, Expr *Capture,
3890 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3891 if (SemaRef.CurContext->isDependentContext())
3892 return ExprResult(Capture);
3893 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
3894 return SemaRef.PerformImplicitConversion(
3895 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
3896 /*AllowExplicit=*/true);
3897 auto I = Captures.find(Capture);
3898 if (I != Captures.end())
3899 return buildCapture(SemaRef, Capture, I->second);
3900 DeclRefExpr *Ref = nullptr;
3901 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
3902 Captures[Capture] = Ref;
3903 return Res;
3904}
3905
3906/// \brief Build the expression to calculate the number of iterations.
3907Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3908 Scope *S, const bool LimitedType,
3909 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
3910 ExprResult Diff;
3911 auto VarType = LCDecl->getType().getNonReferenceType();
18
Called C++ object pointer is null
3912 if (VarType->isIntegerType() || VarType->isPointerType() ||
3913 SemaRef.getLangOpts().CPlusPlus) {
3914 // Upper - Lower
3915 auto *UBExpr = TestIsLessOp ? UB : LB;
3916 auto *LBExpr = TestIsLessOp ? LB : UB;
3917 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3918 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3919 if (!Upper || !Lower)
3920 return nullptr;
3921
3922 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3923
3924 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3925 // BuildBinOp already emitted error, this one is to point user to upper
3926 // and lower bound, and to tell what is passed to 'operator-'.
3927 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3928 << Upper->getSourceRange() << Lower->getSourceRange();
3929 return nullptr;
3930 }
3931 }
3932
3933 if (!Diff.isUsable())
3934 return nullptr;
3935
3936 // Upper - Lower [- 1]
3937 if (TestIsStrictOp)
3938 Diff = SemaRef.BuildBinOp(
3939 S, DefaultLoc, BO_Sub, Diff.get(),
3940 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3941 if (!Diff.isUsable())
3942 return nullptr;
3943
3944 // Upper - Lower [- 1] + Step
3945 auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
3946 if (!NewStep.isUsable())
3947 return nullptr;
3948 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3949 if (!Diff.isUsable())
3950 return nullptr;
3951
3952 // Parentheses (for dumping/debugging purposes only).
3953 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3954 if (!Diff.isUsable())
3955 return nullptr;
3956
3957 // (Upper - Lower [- 1] + Step) / Step
3958 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3959 if (!Diff.isUsable())
3960 return nullptr;
3961
3962 // OpenMP runtime requires 32-bit or 64-bit loop variables.
3963 QualType Type = Diff.get()->getType();
3964 auto &C = SemaRef.Context;
3965 bool UseVarType = VarType->hasIntegerRepresentation() &&
3966 C.getTypeSize(Type) > C.getTypeSize(VarType);
3967 if (!Type->isIntegerType() || UseVarType) {
3968 unsigned NewSize =
3969 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3970 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3971 : Type->hasSignedIntegerRepresentation();
3972 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3973 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3974 Diff = SemaRef.PerformImplicitConversion(
3975 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3976 if (!Diff.isUsable())
3977 return nullptr;
3978 }
3979 }
3980 if (LimitedType) {
3981 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3982 if (NewSize != C.getTypeSize(Type)) {
3983 if (NewSize < C.getTypeSize(Type)) {
3984 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3984, __extension__ __PRETTY_FUNCTION__))
;
3985 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3986 << InitSrcRange << ConditionSrcRange;
3987 }
3988 QualType NewType = C.getIntTypeForBitwidth(
3989 NewSize, Type->hasSignedIntegerRepresentation() ||
3990 C.getTypeSize(Type) < NewSize);
3991 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
3992 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
3993 Sema::AA_Converting, true);
3994 if (!Diff.isUsable())
3995 return nullptr;
3996 }
3997 }
3998 }
3999
4000 return Diff.get();
4001}
4002
4003Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4004 Scope *S, Expr *Cond,
4005 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4006 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4007 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4008 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4009
4010 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4011 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4012 if (!NewLB.isUsable() || !NewUB.isUsable())
4013 return nullptr;
4014
4015 auto CondExpr = SemaRef.BuildBinOp(
4016 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4017 : (TestIsStrictOp ? BO_GT : BO_GE),
4018 NewLB.get(), NewUB.get());
4019 if (CondExpr.isUsable()) {
4020 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4021 SemaRef.Context.BoolTy))
4022 CondExpr = SemaRef.PerformImplicitConversion(
4023 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4024 /*AllowExplicit=*/true);
4025 }
4026 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4027 // Otherwise use original loop conditon and evaluate it in runtime.
4028 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4029}
4030
4031/// \brief Build reference expression to the counter be used for codegen.
4032DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4033 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4034 auto *VD = dyn_cast<VarDecl>(LCDecl);
4035 if (!VD) {
4036 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4037 auto *Ref = buildDeclRefExpr(
4038 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4039 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4040 // If the loop control decl is explicitly marked as private, do not mark it
4041 // as captured again.
4042 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4043 Captures.insert(std::make_pair(LCRef, Ref));
4044 return Ref;
4045 }
4046 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4047 DefaultLoc);
4048}
4049
4050Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4051 if (LCDecl && !LCDecl->isInvalidDecl()) {
4052 auto Type = LCDecl->getType().getNonReferenceType();
4053 auto *PrivateVar =
4054 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4055 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4056 if (PrivateVar->isInvalidDecl())
4057 return nullptr;
4058 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4059 }
4060 return nullptr;
4061}
4062
4063/// \brief Build initialization of the counter to be used for codegen.
4064Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
4065
4066/// \brief Build step of the counter be used for codegen.
4067Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4068
4069/// \brief Iteration space of a single for loop.
4070struct LoopIterationSpace final {
4071 /// \brief Condition of the loop.
4072 Expr *PreCond = nullptr;
4073 /// \brief This expression calculates the number of iterations in the loop.
4074 /// It is always possible to calculate it before starting the loop.
4075 Expr *NumIterations = nullptr;
4076 /// \brief The loop counter variable.
4077 Expr *CounterVar = nullptr;
4078 /// \brief Private loop counter variable.
4079 Expr *PrivateCounterVar = nullptr;
4080 /// \brief This is initializer for the initial value of #CounterVar.
4081 Expr *CounterInit = nullptr;
4082 /// \brief This is step for the #CounterVar used to generate its update:
4083 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4084 Expr *CounterStep = nullptr;
4085 /// \brief Should step be subtracted?
4086 bool Subtract = false;
4087 /// \brief Source range of the loop init.
4088 SourceRange InitSrcRange;
4089 /// \brief Source range of the loop condition.
4090 SourceRange CondSrcRange;
4091 /// \brief Source range of the loop increment.
4092 SourceRange IncSrcRange;
4093};
4094
4095} // namespace
4096
4097void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4098 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4098, __extension__ __PRETTY_FUNCTION__))
;
4099 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4099, __extension__ __PRETTY_FUNCTION__))
;
4100 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
4101 if (AssociatedLoops > 0 &&
4102 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4103 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4104 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4105 if (auto *D = ISC.GetLoopDecl()) {
4106 auto *VD = dyn_cast<VarDecl>(D);
4107 if (!VD) {
4108 if (auto *Private = IsOpenMPCapturedDecl(D))
4109 VD = Private;
4110 else {
4111 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4112 /*WithInit=*/false);
4113 VD = cast<VarDecl>(Ref->getDecl());
4114 }
4115 }
4116 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
4117 }
4118 }
4119 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
4120 }
4121}
4122
4123/// \brief Called on a for stmt to check and extract its iteration space
4124/// for further processing (such as collapsing).
4125static bool CheckOpenMPIterationSpace(
4126 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4127 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4128 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4129 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4130 LoopIterationSpace &ResultIterSpace,
4131 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4132 // OpenMP [2.6, Canonical Loop Form]
4133 // for (init-expr; test-expr; incr-expr) structured-block
4134 auto *For = dyn_cast_or_null<ForStmt>(S);
4135 if (!For) {
7
Assuming 'For' is non-null
8
Taking false branch
4136 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4137 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4138 << getOpenMPDirectiveName(DKind) << NestedLoopCount
4139 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4140 if (NestedLoopCount > 1) {
4141 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4142 SemaRef.Diag(DSA.getConstructLoc(),
4143 diag::note_omp_collapse_ordered_expr)
4144 << 2 << CollapseLoopCountExpr->getSourceRange()
4145 << OrderedLoopCountExpr->getSourceRange();
4146 else if (CollapseLoopCountExpr)
4147 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4148 diag::note_omp_collapse_ordered_expr)
4149 << 0 << CollapseLoopCountExpr->getSourceRange();
4150 else
4151 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4152 diag::note_omp_collapse_ordered_expr)
4153 << 1 << OrderedLoopCountExpr->getSourceRange();
4154 }
4155 return true;
4156 }
4157 assert(For->getBody())(static_cast <bool> (For->getBody()) ? void (0) : __assert_fail
("For->getBody()", "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4157, __extension__ __PRETTY_FUNCTION__))
;
4158
4159 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
9
Calling constructor for 'OpenMPIterationSpaceChecker'
11
Returning from constructor for 'OpenMPIterationSpaceChecker'
4160
4161 // Check init.
4162 auto Init = For->getInit();
4163 if (ISC.CheckInit(Init))
12
Taking false branch
4164 return true;
4165
4166 bool HasErrors = false;
4167
4168 // Check loop variable's type.
4169 if (auto *LCDecl = ISC.GetLoopDecl()) {
13
Taking false branch
4170 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4171
4172 // OpenMP [2.6, Canonical Loop Form]
4173 // Var is one of the following:
4174 // A variable of signed or unsigned integer type.
4175 // For C++, a variable of a random access iterator type.
4176 // For C, a variable of a pointer type.
4177 auto VarType = LCDecl->getType().getNonReferenceType();
4178 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4179 !VarType->isPointerType() &&
4180 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4181 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4182 << SemaRef.getLangOpts().CPlusPlus;
4183 HasErrors = true;
4184 }
4185
4186 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4187 // a Construct
4188 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4189 // parallel for construct is (are) private.
4190 // The loop iteration variable in the associated for-loop of a simd
4191 // construct with just one associated for-loop is linear with a
4192 // constant-linear-step that is the increment of the associated for-loop.
4193 // Exclude loop var from the list of variables with implicitly defined data
4194 // sharing attributes.
4195 VarsWithImplicitDSA.erase(LCDecl);
4196
4197 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4198 // in a Construct, C/C++].
4199 // The loop iteration variable in the associated for-loop of a simd
4200 // construct with just one associated for-loop may be listed in a linear
4201 // clause with a constant-linear-step that is the increment of the
4202 // associated for-loop.
4203 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4204 // parallel for construct may be listed in a private or lastprivate clause.
4205 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4206 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4207 // declared in the loop and it is predetermined as a private.
4208 auto PredeterminedCKind =
4209 isOpenMPSimdDirective(DKind)
4210 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4211 : OMPC_private;
4212 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4213 DVar.CKind != PredeterminedCKind) ||
4214 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4215 isOpenMPDistributeDirective(DKind)) &&
4216 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4217 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4218 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4219 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4220 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4221 << getOpenMPClauseName(PredeterminedCKind);
4222 if (DVar.RefExpr == nullptr)
4223 DVar.CKind = PredeterminedCKind;
4224 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4225 HasErrors = true;
4226 } else if (LoopDeclRefExpr != nullptr) {
4227 // Make the loop iteration variable private (for worksharing constructs),
4228 // linear (for simd directives with the only one associated loop) or
4229 // lastprivate (for simd directives with several collapsed or ordered
4230 // loops).
4231 if (DVar.CKind == OMPC_unknown)
4232 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4233 [](OpenMPDirectiveKind) -> bool { return true; },
4234 /*FromParent=*/false);
4235 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4236 }
4237
4238 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4238, __extension__ __PRETTY_FUNCTION__))
;
4239
4240 // Check test-expr.
4241 HasErrors |= ISC.CheckCond(For->getCond());
4242
4243 // Check incr-expr.
4244 HasErrors |= ISC.CheckInc(For->getInc());
4245 }
4246
4247 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
14
Assuming the condition is false
15
Taking false branch
4248 return HasErrors;
4249
4250 // Build the loop's iteration space representation.
4251 ResultIterSpace.PreCond =
4252 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4253 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
17
Calling 'OpenMPIterationSpaceChecker::BuildNumIterations'
4254 DSA.getCurScope(),
4255 (isOpenMPWorksharingDirective(DKind) ||
16
Assuming the condition is true
4256 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4257 Captures);
4258 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4259 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4260 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4261 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4262 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4263 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4264 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4265 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4266
4267 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4268 ResultIterSpace.NumIterations == nullptr ||
4269 ResultIterSpace.CounterVar == nullptr ||
4270 ResultIterSpace.PrivateCounterVar == nullptr ||
4271 ResultIterSpace.CounterInit == nullptr ||
4272 ResultIterSpace.CounterStep == nullptr);
4273
4274 return HasErrors;
4275}
4276
4277/// \brief Build 'VarRef = Start.
4278static ExprResult
4279BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4280 ExprResult Start,
4281 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4282 // Build 'VarRef = Start.
4283 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4284 if (!NewStart.isUsable())
4285 return ExprError();
4286 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4287 VarRef.get()->getType())) {
4288 NewStart = SemaRef.PerformImplicitConversion(
4289 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4290 /*AllowExplicit=*/true);
4291 if (!NewStart.isUsable())
4292 return ExprError();
4293 }
4294
4295 auto Init =
4296 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4297 return Init;
4298}
4299
4300/// \brief Build 'VarRef = Start + Iter * Step'.
4301static ExprResult
4302BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc,
4303 ExprResult VarRef, ExprResult Start, ExprResult Iter,
4304 ExprResult Step, bool Subtract,
4305 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4306 // Add parentheses (for debugging purposes only).
4307 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4308 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4309 !Step.isUsable())
4310 return ExprError();
4311
4312 ExprResult NewStep = Step;
4313 if (Captures)
4314 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4315 if (NewStep.isInvalid())
4316 return ExprError();
4317 ExprResult Update =
4318 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4319 if (!Update.isUsable())
4320 return ExprError();
4321
4322 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4323 // 'VarRef = Start (+|-) Iter * Step'.
4324 ExprResult NewStart = Start;
4325 if (Captures)
4326 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4327 if (NewStart.isInvalid())
4328 return ExprError();
4329
4330 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4331 ExprResult SavedUpdate = Update;
4332 ExprResult UpdateVal;
4333 if (VarRef.get()->getType()->isOverloadableType() ||
4334 NewStart.get()->getType()->isOverloadableType() ||
4335 Update.get()->getType()->isOverloadableType()) {
4336 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4337 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4338 Update =
4339 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4340 if (Update.isUsable()) {
4341 UpdateVal =
4342 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4343 VarRef.get(), SavedUpdate.get());
4344 if (UpdateVal.isUsable()) {
4345 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4346 UpdateVal.get());
4347 }
4348 }
4349 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4350 }
4351
4352 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4353 if (!Update.isUsable() || !UpdateVal.isUsable()) {
4354 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4355 NewStart.get(), SavedUpdate.get());
4356 if (!Update.isUsable())
4357 return ExprError();
4358
4359 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4360 VarRef.get()->getType())) {
4361 Update = SemaRef.PerformImplicitConversion(
4362 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4363 if (!Update.isUsable())
4364 return ExprError();
4365 }
4366
4367 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4368 }
4369 return Update;
4370}
4371
4372/// \brief Convert integer expression \a E to make it have at least \a Bits
4373/// bits.
4374static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4375 if (E == nullptr)
4376 return ExprError();
4377 auto &C = SemaRef.Context;
4378 QualType OldType = E->getType();
4379 unsigned HasBits = C.getTypeSize(OldType);
4380 if (HasBits >= Bits)
4381 return ExprResult(E);
4382 // OK to convert to signed, because new type has more bits than old.
4383 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4384 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4385 true);
4386}
4387
4388/// \brief Check if the given expression \a E is a constant integer that fits
4389/// into \a Bits bits.
4390static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4391 if (E == nullptr)
4392 return false;
4393 llvm::APSInt Result;
4394 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4395 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4396 return false;
4397}
4398
4399/// Build preinits statement for the given declarations.
4400static Stmt *buildPreInits(ASTContext &Context,
4401 MutableArrayRef<Decl *> PreInits) {
4402 if (!PreInits.empty()) {
4403 return new (Context) DeclStmt(
4404 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4405 SourceLocation(), SourceLocation());
4406 }
4407 return nullptr;
4408}
4409
4410/// Build preinits statement for the given declarations.
4411static Stmt *
4412buildPreInits(ASTContext &Context,
4413 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4414 if (!Captures.empty()) {
4415 SmallVector<Decl *, 16> PreInits;
4416 for (auto &Pair : Captures)
4417 PreInits.push_back(Pair.second->getDecl());
4418 return buildPreInits(Context, PreInits);
4419 }
4420 return nullptr;
4421}
4422
4423/// Build postupdate expression for the given list of postupdates expressions.
4424static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4425 Expr *PostUpdate = nullptr;
4426 if (!PostUpdates.empty()) {
4427 for (auto *E : PostUpdates) {
4428 Expr *ConvE = S.BuildCStyleCastExpr(
4429 E->getExprLoc(),
4430 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4431 E->getExprLoc(), E)
4432 .get();
4433 PostUpdate = PostUpdate
4434 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4435 PostUpdate, ConvE)
4436 .get()
4437 : ConvE;
4438 }
4439 }
4440 return PostUpdate;
4441}
4442
4443/// \brief Called on a for stmt to check itself and nested loops (if any).
4444/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4445/// number of collapsed loops otherwise.
4446static unsigned
4447CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4448 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4449 DSAStackTy &DSA,
4450 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4451 OMPLoopDirective::HelperExprs &Built) {
4452 unsigned NestedLoopCount = 1;
4453 if (CollapseLoopCountExpr) {
1
Assuming 'CollapseLoopCountExpr' is null
2
Taking false branch
4454 // Found 'collapse' clause - calculate collapse number.
4455 llvm::APSInt Result;
4456 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4457 NestedLoopCount = Result.getLimitedValue();
4458 }
4459 if (OrderedLoopCountExpr) {
3
Assuming 'OrderedLoopCountExpr' is null
4
Taking false branch
4460 // Found 'ordered' clause - calculate collapse number.
4461 llvm::APSInt Result;
4462 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4463 if (Result.getLimitedValue() < NestedLoopCount) {
4464 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4465 diag::err_omp_wrong_ordered_loop_count)
4466 << OrderedLoopCountExpr->getSourceRange();
4467 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4468 diag::note_collapse_loop_count)
4469 << CollapseLoopCountExpr->getSourceRange();
4470 }
4471 NestedLoopCount = Result.getLimitedValue();
4472 }
4473 }
4474 // This is helper routine for loop directives (e.g., 'for', 'simd',
4475 // 'for simd', etc.).
4476 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4477 SmallVector<LoopIterationSpace, 4> IterSpaces;
4478 IterSpaces.resize(NestedLoopCount);
4479 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4480 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5
Loop condition is true. Entering loop body
4481 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
6
Calling 'CheckOpenMPIterationSpace'
4482 NestedLoopCount, CollapseLoopCountExpr,
4483 OrderedLoopCountExpr, VarsWithImplicitDSA,
4484 IterSpaces[Cnt], Captures))
4485 return 0;
4486 // Move on to the next nested for loop, or to the loop body.
4487 // OpenMP [2.8.1, simd construct, Restrictions]
4488 // All loops associated with the construct must be perfectly nested; that
4489 // is, there must be no intervening code nor any OpenMP directive between
4490 // any two loops.
4491 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4492 }
4493
4494 Built.clear(/* size */ NestedLoopCount);
4495
4496 if (SemaRef.CurContext->isDependentContext())
4497 return NestedLoopCount;
4498
4499 // An example of what is generated for the following code:
4500 //
4501 // #pragma omp simd collapse(2) ordered(2)
4502 // for (i = 0; i < NI; ++i)
4503 // for (k = 0; k < NK; ++k)
4504 // for (j = J0; j < NJ; j+=2) {
4505 // <loop body>
4506 // }
4507 //
4508 // We generate the code below.
4509 // Note: the loop body may be outlined in CodeGen.
4510 // Note: some counters may be C++ classes, operator- is used to find number of
4511 // iterations and operator+= to calculate counter value.
4512 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4513 // or i64 is currently supported).
4514 //
4515 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4516 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4517 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4518 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4519 // // similar updates for vars in clauses (e.g. 'linear')
4520 // <loop body (using local i and j)>
4521 // }
4522 // i = NI; // assign final values of counters
4523 // j = NJ;
4524 //
4525
4526 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4527 // the iteration counts of the collapsed for loops.
4528 // Precondition tests if there is at least one iteration (all conditions are
4529 // true).
4530 auto PreCond = ExprResult(IterSpaces[0].PreCond);
4531 auto N0 = IterSpaces[0].NumIterations;
4532 ExprResult LastIteration32 = WidenIterationCount(
4533 32 /* Bits */, SemaRef
4534 .PerformImplicitConversion(
4535 N0->IgnoreImpCasts(), N0->getType(),
4536 Sema::AA_Converting, /*AllowExplicit=*/true)
4537 .get(),
4538 SemaRef);
4539 ExprResult LastIteration64 = WidenIterationCount(
4540 64 /* Bits */, SemaRef
4541 .PerformImplicitConversion(
4542 N0->IgnoreImpCasts(), N0->getType(),
4543 Sema::AA_Converting, /*AllowExplicit=*/true)
4544 .get(),
4545 SemaRef);
4546
4547 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4548 return NestedLoopCount;
4549
4550 auto &C = SemaRef.Context;
4551 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4552
4553 Scope *CurScope = DSA.getCurScope();
4554 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4555 if (PreCond.isUsable()) {
4556 PreCond =
4557 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4558 PreCond.get(), IterSpaces[Cnt].PreCond);
4559 }
4560 auto N = IterSpaces[Cnt].NumIterations;
4561 SourceLocation Loc = N->getExprLoc();
4562 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4563 if (LastIteration32.isUsable())
4564 LastIteration32 = SemaRef.BuildBinOp(
4565 CurScope, Loc, BO_Mul, LastIteration32.get(),
4566 SemaRef
4567 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4568 Sema::AA_Converting,
4569 /*AllowExplicit=*/true)
4570 .get());
4571 if (LastIteration64.isUsable())
4572 LastIteration64 = SemaRef.BuildBinOp(
4573 CurScope, Loc, BO_Mul, LastIteration64.get(),
4574 SemaRef
4575 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4576 Sema::AA_Converting,
4577 /*AllowExplicit=*/true)
4578 .get());
4579 }
4580
4581 // Choose either the 32-bit or 64-bit version.
4582 ExprResult LastIteration = LastIteration64;
4583 if (LastIteration32.isUsable() &&
4584 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4585 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4586 FitsInto(
4587 32 /* Bits */,
4588 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4589 LastIteration64.get(), SemaRef)))
4590 LastIteration = LastIteration32;
4591 QualType VType = LastIteration.get()->getType();
4592 QualType RealVType = VType;
4593 QualType StrideVType = VType;
4594 if (isOpenMPTaskLoopDirective(DKind)) {
4595 VType =
4596 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4597 StrideVType =
4598 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4599 }
4600
4601 if (!LastIteration.isUsable())
4602 return 0;
4603
4604 // Save the number of iterations.
4605 ExprResult NumIterations = LastIteration;
4606 {
4607 LastIteration = SemaRef.BuildBinOp(
4608 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4609 LastIteration.get(),
4610 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4611 if (!LastIteration.isUsable())
4612 return 0;
4613 }
4614
4615 // Calculate the last iteration number beforehand instead of doing this on
4616 // each iteration. Do not do this if the number of iterations may be kfold-ed.
4617 llvm::APSInt Result;
4618 bool IsConstant =
4619 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4620 ExprResult CalcLastIteration;
4621 if (!IsConstant) {
4622 ExprResult SaveRef =
4623 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4624 LastIteration = SaveRef;
4625
4626 // Prepare SaveRef + 1.
4627 NumIterations = SemaRef.BuildBinOp(
4628 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4629 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4630 if (!NumIterations.isUsable())
4631 return 0;
4632 }
4633
4634 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4635
4636 // Build variables passed into runtime, necessary for worksharing directives.
4637 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4638 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4639 isOpenMPDistributeDirective(DKind)) {
4640 // Lower bound variable, initialized with zero.
4641 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4642 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4643 SemaRef.AddInitializerToDecl(LBDecl,
4644 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4645 /*DirectInit*/ false);
4646
4647 // Upper bound variable, initialized with last iteration number.
4648 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4649 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4650 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4651 /*DirectInit*/ false);
4652
4653 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4654 // This will be used to implement clause 'lastprivate'.
4655 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4656 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4657 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4658 SemaRef.AddInitializerToDecl(ILDecl,
4659 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4660 /*DirectInit*/ false);
4661
4662 // Stride variable returned by runtime (we initialize it to 1 by default).
4663 VarDecl *STDecl =
4664 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4665 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4666 SemaRef.AddInitializerToDecl(STDecl,
4667 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4668 /*DirectInit*/ false);
4669
4670 // Build expression: UB = min(UB, LastIteration)
4671 // It is necessary for CodeGen of directives with static scheduling.
4672 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4673 UB.get(), LastIteration.get());
4674 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4675 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4676 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4677 CondOp.get());
4678 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4679
4680 // If we have a combined directive that combines 'distribute', 'for' or
4681 // 'simd' we need to be able to access the bounds of the schedule of the
4682 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4683 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4684 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4685
4686 // Lower bound variable, initialized with zero.
4687 VarDecl *CombLBDecl =
4688 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4689 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4690 SemaRef.AddInitializerToDecl(
4691 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4692 /*DirectInit*/ false);
4693
4694 // Upper bound variable, initialized with last iteration number.
4695 VarDecl *CombUBDecl =
4696 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4697 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4698 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4699 /*DirectInit*/ false);
4700
4701 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4702 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4703 ExprResult CombCondOp =
4704 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4705 LastIteration.get(), CombUB.get());
4706 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4707 CombCondOp.get());
4708 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4709
4710 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4711 // We expect to have at least 2 more parameters than the 'parallel'
4712 // directive does - the lower and upper bounds of the previous schedule.
4713 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4714, __extension__ __PRETTY_FUNCTION__))
4714 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4714, __extension__ __PRETTY_FUNCTION__))
;
4715
4716 // Set the proper type for the bounds given what we learned from the
4717 // enclosed loops.
4718 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4719 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4720
4721 // Previous lower and upper bounds are obtained from the region
4722 // parameters.
4723 PrevLB =
4724 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4725 PrevUB =
4726 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4727 }
4728 }
4729
4730 // Build the iteration variable and its initialization before loop.
4731 ExprResult IV;
4732 ExprResult Init, CombInit;
4733 {
4734 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4735 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4736 Expr *RHS =
4737 (isOpenMPWorksharingDirective(DKind) ||
4738 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4739 ? LB.get()
4740 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4741 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4742 Init = SemaRef.ActOnFinishFullExpr(Init.get());
4743
4744 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4745 Expr *CombRHS =
4746 (isOpenMPWorksharingDirective(DKind) ||
4747 isOpenMPTaskLoopDirective(DKind) ||
4748 isOpenMPDistributeDirective(DKind))
4749 ? CombLB.get()
4750 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4751 CombInit =
4752 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4753 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4754 }
4755 }
4756
4757 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4758 SourceLocation CondLoc;
4759 ExprResult Cond =
4760 (isOpenMPWorksharingDirective(DKind) ||
4761 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4762 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4763 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4764 NumIterations.get());
4765 ExprResult CombCond;
4766 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4767 CombCond =
4768 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4769 }
4770 // Loop increment (IV = IV + 1)
4771 SourceLocation IncLoc;
4772 ExprResult Inc =
4773 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4774 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4775 if (!Inc.isUsable())
4776 return 0;
4777 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4778 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4779 if (!Inc.isUsable())
4780 return 0;
4781
4782 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4783 // Used for directives with static scheduling.
4784 // In combined construct, add combined version that use CombLB and CombUB
4785 // base variables for the update
4786 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4787 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4788 isOpenMPDistributeDirective(DKind)) {
4789 // LB + ST
4790 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4791 if (!NextLB.isUsable())
4792 return 0;
4793 // LB = LB + ST
4794 NextLB =
4795 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4796 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4797 if (!NextLB.isUsable())
4798 return 0;
4799 // UB + ST
4800 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4801 if (!NextUB.isUsable())
4802 return 0;
4803 // UB = UB + ST
4804 NextUB =
4805 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4806 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4807 if (!NextUB.isUsable())
4808 return 0;
4809 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4810 CombNextLB =
4811 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4812 if (!NextLB.isUsable())
4813 return 0;
4814 // LB = LB + ST
4815 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4816 CombNextLB.get());
4817 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4818 if (!CombNextLB.isUsable())
4819 return 0;
4820 // UB + ST
4821 CombNextUB =
4822 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4823 if (!CombNextUB.isUsable())
4824 return 0;
4825 // UB = UB + ST
4826 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4827 CombNextUB.get());
4828 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4829 if (!CombNextUB.isUsable())
4830 return 0;
4831 }
4832 }
4833
4834 // Create increment expression for distribute loop when combined in a same
4835 // directive with for as IV = IV + ST; ensure upper bound expression based
4836 // on PrevUB instead of NumIterations - used to implement 'for' when found
4837 // in combination with 'distribute', like in 'distribute parallel for'
4838 SourceLocation DistIncLoc;
4839 ExprResult DistCond, DistInc, PrevEUB;
4840 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4841 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4842 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4842, __extension__ __PRETTY_FUNCTION__))
;
4843
4844 DistInc =
4845 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4846 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4846, __extension__ __PRETTY_FUNCTION__))
;
4847 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4848 DistInc.get());
4849 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4850 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4850, __extension__ __PRETTY_FUNCTION__))
;
4851
4852 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4853 // construct
4854 SourceLocation DistEUBLoc;
4855 ExprResult IsUBGreater =
4856 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4857 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4858 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4859 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4860 CondOp.get());
4861 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4862 }
4863
4864 // Build updates and final values of the loop counters.
4865 bool HasErrors = false;
4866 Built.Counters.resize(NestedLoopCount);
4867 Built.Inits.resize(NestedLoopCount);
4868 Built.Updates.resize(NestedLoopCount);
4869 Built.Finals.resize(NestedLoopCount);
4870 SmallVector<Expr *, 4> LoopMultipliers;
4871 {
4872 ExprResult Div;
4873 // Go from inner nested loop to outer.
4874 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4875 LoopIterationSpace &IS = IterSpaces[Cnt];
4876 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4877 // Build: Iter = (IV / Div) % IS.NumIters
4878 // where Div is product of previous iterations' IS.NumIters.
4879 ExprResult Iter;
4880 if (Div.isUsable()) {
4881 Iter =
4882 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4883 } else {
4884 Iter = IV;
4885 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4886, __extension__ __PRETTY_FUNCTION__))
4886 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4886, __extension__ __PRETTY_FUNCTION__))
;
4887 }
4888
4889 if (Cnt != 0 && Iter.isUsable())
4890 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4891 IS.NumIterations);
4892 if (!Iter.isUsable()) {
4893 HasErrors = true;
4894 break;
4895 }
4896
4897 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4898 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4899 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
4900 IS.CounterVar->getExprLoc(),
4901 /*RefersToCapture=*/true);
4902 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4903 IS.CounterInit, Captures);
4904 if (!Init.isUsable()) {
4905 HasErrors = true;
4906 break;
4907 }
4908 ExprResult Update = BuildCounterUpdate(
4909 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4910 IS.CounterStep, IS.Subtract, &Captures);
4911 if (!Update.isUsable()) {
4912 HasErrors = true;
4913 break;
4914 }
4915
4916 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4917 ExprResult Final = BuildCounterUpdate(
4918 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4919 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4920 if (!Final.isUsable()) {
4921 HasErrors = true;
4922 break;
4923 }
4924
4925 // Build Div for the next iteration: Div <- Div * IS.NumIters
4926 if (Cnt != 0) {
4927 if (Div.isUnset())
4928 Div = IS.NumIterations;
4929 else
4930 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4931 IS.NumIterations);
4932
4933 // Add parentheses (for debugging purposes only).
4934 if (Div.isUsable())
4935 Div = tryBuildCapture(SemaRef, Div.get(), Captures);
4936 if (!Div.isUsable()) {
4937 HasErrors = true;
4938 break;
4939 }
4940 LoopMultipliers.push_back(Div.get());
4941 }
4942 if (!Update.isUsable() || !Final.isUsable()) {
4943 HasErrors = true;
4944 break;
4945 }
4946 // Save results
4947 Built.Counters[Cnt] = IS.CounterVar;
4948 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4949 Built.Inits[Cnt] = Init.get();
4950 Built.Updates[Cnt] = Update.get();
4951 Built.Finals[Cnt] = Final.get();
4952 }
4953 }
4954
4955 if (HasErrors)
4956 return 0;
4957
4958 // Save results
4959 Built.IterationVarRef = IV.get();
4960 Built.LastIteration = LastIteration.get();
4961 Built.NumIterations = NumIterations.get();
4962 Built.CalcLastIteration =
4963 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4964 Built.PreCond = PreCond.get();
4965 Built.PreInits = buildPreInits(C, Captures);
4966 Built.Cond = Cond.get();
4967 Built.Init = Init.get();
4968 Built.Inc = Inc.get();
4969 Built.LB = LB.get();
4970 Built.UB = UB.get();
4971 Built.IL = IL.get();
4972 Built.ST = ST.get();
4973 Built.EUB = EUB.get();
4974 Built.NLB = NextLB.get();
4975 Built.NUB = NextUB.get();
4976 Built.PrevLB = PrevLB.get();
4977 Built.PrevUB = PrevUB.get();
4978 Built.DistInc = DistInc.get();
4979 Built.PrevEUB = PrevEUB.get();
4980 Built.DistCombinedFields.LB = CombLB.get();
4981 Built.DistCombinedFields.UB = CombUB.get();
4982 Built.DistCombinedFields.EUB = CombEUB.get();
4983 Built.DistCombinedFields.Init = CombInit.get();
4984 Built.DistCombinedFields.Cond = CombCond.get();
4985 Built.DistCombinedFields.NLB = CombNextLB.get();
4986 Built.DistCombinedFields.NUB = CombNextUB.get();
4987
4988 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
4989 // Fill data for doacross depend clauses.
4990 for (auto Pair : DSA.getDoacrossDependClauses()) {
4991 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4992 Pair.first->setCounterValue(CounterVal);
4993 else {
4994 if (NestedLoopCount != Pair.second.size() ||
4995 NestedLoopCount != LoopMultipliers.size() + 1) {
4996 // Erroneous case - clause has some problems.
4997 Pair.first->setCounterValue(CounterVal);
4998 continue;
4999 }
5000 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5000, __extension__ __PRETTY_FUNCTION__))
;
5001 auto I = Pair.second.rbegin();
5002 auto IS = IterSpaces.rbegin();
5003 auto ILM = LoopMultipliers.rbegin();
5004 Expr *UpCounterVal = CounterVal;
5005 Expr *Multiplier = nullptr;
5006 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5007 if (I->first) {
5008 assert(IS->CounterStep)(static_cast <bool> (IS->CounterStep) ? void (0) : __assert_fail
("IS->CounterStep", "/build/llvm-toolchain-snapshot-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5008, __extension__ __PRETTY_FUNCTION__))
;
5009 Expr *NormalizedOffset =
5010 SemaRef
5011 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5012 I->first, IS->CounterStep)
5013 .get();
5014 if (Multiplier) {
5015 NormalizedOffset =
5016 SemaRef
5017 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5018 NormalizedOffset, Multiplier)
5019 .get();
5020 }
5021 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5021, __extension__ __PRETTY_FUNCTION__))
;
5022 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5023 UpCounterVal = SemaRef
5024 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5025 UpCounterVal, NormalizedOffset)
5026 .get();
5027 }
5028 Multiplier = *ILM;
5029 ++I;
5030 ++IS;
5031 ++ILM;
5032 }
5033 Pair.first->setCounterValue(UpCounterVal);
5034 }
5035 }
5036
5037 return NestedLoopCount;
5038}
5039
5040static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5041 auto CollapseClauses =
5042 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5043 if (CollapseClauses.begin() != CollapseClauses.end())
5044 return (*CollapseClauses.begin())->getNumForLoops();
5045 return nullptr;
5046}
5047
5048static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5049 auto OrderedClauses =
5050 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5051 if (OrderedClauses.begin() != OrderedClauses.end())
5052 return (*OrderedClauses.begin())->getNumForLoops();
5053 return nullptr;
5054}
5055
5056static bool checkSimdlenSafelenSpecified(Sema &S,
5057 const ArrayRef<OMPClause *> Clauses) {
5058 OMPSafelenClause *Safelen = nullptr;
5059 OMPSimdlenClause *Simdlen = nullptr;
5060
5061 for (auto *Clause : Clauses) {
5062 if (Clause->getClauseKind() == OMPC_safelen)
5063 Safelen = cast<OMPSafelenClause>(Clause);
5064 else if (Clause->getClauseKind() == OMPC_simdlen)
5065 Simdlen = cast<OMPSimdlenClause>(Clause);
5066 if (Safelen && Simdlen)
5067 break;
5068 }
5069
5070 if (Simdlen && Safelen) {
5071 llvm::APSInt SimdlenRes, SafelenRes;
5072 auto SimdlenLength = Simdlen->getSimdlen();
5073 auto SafelenLength = Safelen->getSafelen();
5074 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5075 SimdlenLength->isInstantiationDependent() ||
5076 SimdlenLength->containsUnexpandedParameterPack())
5077 return false;
5078 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5079 SafelenLength->isInstantiationDependent() ||
5080 SafelenLength->containsUnexpandedParameterPack())
5081 return false;
5082 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5083 SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5084 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5085 // If both simdlen and safelen clauses are specified, the value of the
5086 // simdlen parameter must be less than or equal to the value of the safelen
5087 // parameter.
5088 if (SimdlenRes > SafelenRes) {
5089 S.Diag(SimdlenLength->getExprLoc(),
5090 diag::err_omp_wrong_simdlen_safelen_values)
5091 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5092 return true;
5093 }
5094 }
5095 return false;
5096}
5097
5098StmtResult Sema::ActOnOpenMPSimdDirective(
5099 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5100 SourceLocation EndLoc,
5101 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5102 if (!AStmt)
5103 return StmtError();
5104
5105 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5105, __extension__ __PRETTY_FUNCTION__))
;
5106 OMPLoopDirective::HelperExprs B;
5107 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5108 // define the nested loops number.
5109 unsigned NestedLoopCount = CheckOpenMPLoop(
5110 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5111 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5112 if (NestedLoopCount == 0)
5113 return StmtError();
5114
5115 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5116, __extension__ __PRETTY_FUNCTION__))
5116 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5116, __extension__ __PRETTY_FUNCTION__))
;
5117
5118 if (!CurContext->isDependentContext()) {
5119 // Finalize the clauses that need pre-built expressions for CodeGen.
5120 for (auto C : Clauses) {
5121 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5122 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5123 B.NumIterations, *this, CurScope,
5124 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5125 return StmtError();
5126 }
5127 }
5128
5129 if (checkSimdlenSafelenSpecified(*this, Clauses))
5130 return StmtError();
5131
5132 getCurFunction()->setHasBranchProtectedScope();
5133 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5134 Clauses, AStmt, B);
5135}
5136
5137StmtResult Sema::ActOnOpenMPForDirective(
5138 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5139 SourceLocation EndLoc,
5140 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5141 if (!AStmt)
5142 return StmtError();
5143
5144 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5144, __extension__ __PRETTY_FUNCTION__))
;
5145 OMPLoopDirective::HelperExprs B;
5146 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5147 // define the nested loops number.
5148 unsigned NestedLoopCount = CheckOpenMPLoop(
5149 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5150 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5151 if (NestedLoopCount == 0)
5152 return StmtError();
5153
5154 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5155, __extension__ __PRETTY_FUNCTION__))
5155 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5155, __extension__ __PRETTY_FUNCTION__))
;
5156
5157 if (!CurContext->isDependentContext()) {
5158 // Finalize the clauses that need pre-built expressions for CodeGen.
5159 for (auto C : Clauses) {
5160 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5162 B.NumIterations, *this, CurScope,
5163 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5164 return StmtError();
5165 }
5166 }
5167
5168 getCurFunction()->setHasBranchProtectedScope();
5169 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5170 Clauses, AStmt, B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5171}
5172
5173StmtResult Sema::ActOnOpenMPForSimdDirective(
5174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5175 SourceLocation EndLoc,
5176 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5177 if (!AStmt)
5178 return StmtError();
5179
5180 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5180, __extension__ __PRETTY_FUNCTION__))
;
5181 OMPLoopDirective::HelperExprs B;
5182 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5183 // define the nested loops number.
5184 unsigned NestedLoopCount =
5185 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5186 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5187 VarsWithImplicitDSA, B);
5188 if (NestedLoopCount == 0)
5189 return StmtError();
5190
5191 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5192, __extension__ __PRETTY_FUNCTION__))
5192 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5192, __extension__ __PRETTY_FUNCTION__))
;
5193
5194 if (!CurContext->isDependentContext()) {
5195 // Finalize the clauses that need pre-built expressions for CodeGen.
5196 for (auto C : Clauses) {
5197 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5198 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5199 B.NumIterations, *this, CurScope,
5200 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5201 return StmtError();
5202 }
5203 }
5204
5205 if (checkSimdlenSafelenSpecified(*this, Clauses))
5206 return StmtError();
5207
5208 getCurFunction()->setHasBranchProtectedScope();
5209 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5210 Clauses, AStmt, B);
5211}
5212
5213StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5214 Stmt *AStmt,
5215 SourceLocation StartLoc,
5216 SourceLocation EndLoc) {
5217 if (!AStmt)
5218 return StmtError();
5219
5220 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5220, __extension__ __PRETTY_FUNCTION__))
;
5221 auto BaseStmt = AStmt;
5222 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5223 BaseStmt = CS->getCapturedStmt();
5224 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5225 auto S = C->children();
5226 if (S.begin() == S.end())
5227 return StmtError();
5228 // All associated statements must be '#pragma omp section' except for
5229 // the first one.
5230 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5231 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5232 if (SectionStmt)
5233 Diag(SectionStmt->getLocStart(),
5234 diag::err_omp_sections_substmt_not_section);
5235 return StmtError();
5236 }
5237 cast<OMPSectionDirective>(SectionStmt)
5238 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5239 }
5240 } else {
5241 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5242 return StmtError();
5243 }
5244
5245 getCurFunction()->setHasBranchProtectedScope();
5246
5247 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5248 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5249}
5250
5251StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5252 SourceLocation StartLoc,
5253 SourceLocation EndLoc) {
5254 if (!AStmt)
5255 return StmtError();
5256
5257 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5257, __extension__ __PRETTY_FUNCTION__))
;
5258
5259 getCurFunction()->setHasBranchProtectedScope();
5260 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5261
5262 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5263 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5264}
5265
5266StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5267 Stmt *AStmt,
5268 SourceLocation StartLoc,
5269 SourceLocation EndLoc) {
5270 if (!AStmt)
5271 return StmtError();
5272
5273 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5273, __extension__ __PRETTY_FUNCTION__))
;
5274
5275 getCurFunction()->setHasBranchProtectedScope();
5276
5277 // OpenMP [2.7.3, single Construct, Restrictions]
5278 // The copyprivate clause must not be used with the nowait clause.
5279 OMPClause *Nowait = nullptr;
5280 OMPClause *Copyprivate = nullptr;
5281 for (auto *Clause : Clauses) {
5282 if (Clause->getClauseKind() == OMPC_nowait)
5283 Nowait = Clause;
5284 else if (Clause->getClauseKind() == OMPC_copyprivate)
5285 Copyprivate = Clause;
5286 if (Copyprivate && Nowait) {
5287 Diag(Copyprivate->getLocStart(),
5288 diag::err_omp_single_copyprivate_with_nowait);
5289 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5290 return StmtError();
5291 }
5292 }
5293
5294 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5295}
5296
5297StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5298 SourceLocation StartLoc,
5299 SourceLocation EndLoc) {
5300 if (!AStmt)
5301 return StmtError();
5302
5303 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5303, __extension__ __PRETTY_FUNCTION__))
;
5304
5305 getCurFunction()->setHasBranchProtectedScope();
5306
5307 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5308}
5309
5310StmtResult Sema::ActOnOpenMPCriticalDirective(
5311 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5312 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5313 if (!AStmt)
5314 return StmtError();
5315
5316 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5316, __extension__ __PRETTY_FUNCTION__))
;
5317
5318 bool ErrorFound = false;
5319 llvm::APSInt Hint;
5320 SourceLocation HintLoc;
5321 bool DependentHint = false;
5322 for (auto *C : Clauses) {
5323 if (C->getClauseKind() == OMPC_hint) {
5324 if (!DirName.getName()) {
5325 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5326 ErrorFound = true;
5327 }
5328 Expr *E = cast<OMPHintClause>(C)->getHint();
5329 if (E->isTypeDependent() || E->isValueDependent() ||
5330 E->isInstantiationDependent())
5331 DependentHint = true;
5332 else {
5333 Hint = E->EvaluateKnownConstInt(Context);
5334 HintLoc = C->getLocStart();
5335 }
5336 }
5337 }
5338 if (ErrorFound)
5339 return StmtError();
5340 auto Pair = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCriticalWithHint(DirName);
5341 if (Pair.first && DirName.getName() && !DependentHint) {
5342 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5343 Diag(StartLoc, diag::err_omp_critical_with_hint);
5344 if (HintLoc.isValid()) {
5345 Diag(HintLoc, diag::note_omp_critical_hint_here)
5346 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5347 } else
5348 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5349 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5350 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5351 << 1
5352 << C->getHint()->EvaluateKnownConstInt(Context).toString(
5353 /*Radix=*/10, /*Signed=*/false);
5354 } else
5355 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5356 }
5357 }
5358
5359 getCurFunction()->setHasBranchProtectedScope();
5360
5361 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5362 Clauses, AStmt);
5363 if (!Pair.first && DirName.getName() && !DependentHint)
5364 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addCriticalWithHint(Dir, Hint);
5365 return Dir;
5366}
5367
5368StmtResult Sema::ActOnOpenMPParallelForDirective(
5369 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5370 SourceLocation EndLoc,
5371 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5372 if (!AStmt)
5373 return StmtError();
5374
5375 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5376 // 1.2.2 OpenMP Language Terminology
5377 // Structured block - An executable statement with a single entry at the
5378 // top and a single exit at the bottom.
5379 // The point of exit cannot be a branch out of the structured block.
5380 // longjmp() and throw() must not violate the entry/exit criteria.
5381 CS->getCapturedDecl()->setNothrow();
5382
5383 OMPLoopDirective::HelperExprs B;
5384 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5385 // define the nested loops number.
5386 unsigned NestedLoopCount =
5387 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5388 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5389 VarsWithImplicitDSA, B);
5390 if (NestedLoopCount == 0)
5391 return StmtError();
5392
5393 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5394, __extension__ __PRETTY_FUNCTION__))
5394 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5394, __extension__ __PRETTY_FUNCTION__))
;
5395
5396 if (!CurContext->isDependentContext()) {
5397 // Finalize the clauses that need pre-built expressions for CodeGen.
5398 for (auto C : Clauses) {
5399 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5400 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5401 B.NumIterations, *this, CurScope,
5402 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5403 return StmtError();
5404 }
5405 }
5406
5407 getCurFunction()->setHasBranchProtectedScope();
5408 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5409 NestedLoopCount, Clauses, AStmt, B,
5410 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5411}
5412
5413StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
5414 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5415 SourceLocation EndLoc,
5416 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5417 if (!AStmt)
5418 return StmtError();
5419
5420 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5421 // 1.2.2 OpenMP Language Terminology
5422 // Structured block - An executable statement with a single entry at the
5423 // top and a single exit at the bottom.
5424 // The point of exit cannot be a branch out of the structured block.
5425 // longjmp() and throw() must not violate the entry/exit criteria.
5426 CS->getCapturedDecl()->setNothrow();
5427
5428 OMPLoopDirective::HelperExprs B;
5429 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5430 // define the nested loops number.
5431 unsigned NestedLoopCount =
5432 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5433 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5434 VarsWithImplicitDSA, B);
5435 if (NestedLoopCount == 0)
5436 return StmtError();
5437
5438 if (!CurContext->isDependentContext()) {
5439 // Finalize the clauses that need pre-built expressions for CodeGen.
5440 for (auto C : Clauses) {
5441 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5442 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5443 B.NumIterations, *this, CurScope,
5444 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5445 return StmtError();
5446 }
5447 }
5448
5449 if (checkSimdlenSafelenSpecified(*this, Clauses))
5450 return StmtError();
5451
5452 getCurFunction()->setHasBranchProtectedScope();
5453 return OMPParallelForSimdDirective::Create(
5454 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5455}
5456
5457StmtResult
5458Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
5459 Stmt *AStmt, SourceLocation StartLoc,
5460 SourceLocation EndLoc) {
5461 if (!AStmt)
5462 return StmtError();
5463
5464 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5464, __extension__ __PRETTY_FUNCTION__))
;
5465 auto BaseStmt = AStmt;
5466 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5467 BaseStmt = CS->getCapturedStmt();
5468 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5469 auto S = C->children();
5470 if (S.begin() == S.end())
5471 return StmtError();
5472 // All associated statements must be '#pragma omp section' except for
5473 // the first one.
5474 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5475 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5476 if (SectionStmt)
5477 Diag(SectionStmt->getLocStart(),
5478 diag::err_omp_parallel_sections_substmt_not_section);
5479 return StmtError();
5480 }
5481 cast<OMPSectionDirective>(SectionStmt)
5482 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5483 }
5484 } else {
5485 Diag(AStmt->getLocStart(),
5486 diag::err_omp_parallel_sections_not_compound_stmt);
5487 return StmtError();
5488 }
5489
5490 getCurFunction()->setHasBranchProtectedScope();
5491
5492 return OMPParallelSectionsDirective::Create(
5493 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5494}
5495
5496StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
5497 Stmt *AStmt, SourceLocation StartLoc,
5498 SourceLocation EndLoc) {
5499 if (!AStmt)
5500 return StmtError();
5501
5502 auto *CS = cast<CapturedStmt>(AStmt);
5503 // 1.2.2 OpenMP Language Terminology
5504 // Structured block - An executable statement with a single entry at the
5505 // top and a single exit at the bottom.
5506 // The point of exit cannot be a branch out of the structured block.
5507 // longjmp() and throw() must not violate the entry/exit criteria.
5508 CS->getCapturedDecl()->setNothrow();
5509
5510 getCurFunction()->setHasBranchProtectedScope();
5511
5512 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5513 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5514}
5515
5516StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
5517 SourceLocation EndLoc) {
5518 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5519}
5520
5521StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
5522 SourceLocation EndLoc) {
5523 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5524}
5525
5526StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
5527 SourceLocation EndLoc) {
5528 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5529}
5530
5531StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
5532 Stmt *AStmt,
5533 SourceLocation StartLoc,
5534 SourceLocation EndLoc) {
5535 if (!AStmt)
5536 return StmtError();
5537
5538 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5538, __extension__ __PRETTY_FUNCTION__))
;
5539
5540 getCurFunction()->setHasBranchProtectedScope();
5541
5542 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5543 AStmt,
5544 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTaskgroupReductionRef());
5545}
5546
5547StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
5548 SourceLocation StartLoc,
5549 SourceLocation EndLoc) {
5550 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5550, __extension__ __PRETTY_FUNCTION__))
;
5551 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5552}
5553
5554StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
5555 Stmt *AStmt,
5556 SourceLocation StartLoc,
5557 SourceLocation EndLoc) {
5558 OMPClause *DependFound = nullptr;
5559 OMPClause *DependSourceClause = nullptr;
5560 OMPClause *DependSinkClause = nullptr;
5561 bool ErrorFound = false;
5562 OMPThreadsClause *TC = nullptr;
5563 OMPSIMDClause *SC = nullptr;
5564 for (auto *C : Clauses) {
5565 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5566 DependFound = C;
5567 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5568 if (DependSourceClause) {
5569 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5570 << getOpenMPDirectiveName(OMPD_ordered)
5571 << getOpenMPClauseName(OMPC_depend) << 2;
5572 ErrorFound = true;
5573 } else
5574 DependSourceClause = C;
5575 if (DependSinkClause) {
5576 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5577 << 0;
5578 ErrorFound = true;
5579 }
5580 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5581 if (DependSourceClause) {
5582 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5583 << 1;
5584 ErrorFound = true;
5585 }
5586 DependSinkClause = C;
5587 }
5588 } else if (C->getClauseKind() == OMPC_threads)
5589 TC = cast<OMPThreadsClause>(C);
5590 else if (C->getClauseKind() == OMPC_simd)
5591 SC = cast<OMPSIMDClause>(C);
5592 }
5593 if (!ErrorFound && !SC &&
5594 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective())) {
5595 // OpenMP [2.8.1,simd Construct, Restrictions]
5596 // An ordered construct with the simd clause is the only OpenMP construct
5597 // that can appear in the simd region.
5598 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5599 ErrorFound = true;
5600 } else if (DependFound && (TC || SC)) {
5601 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5602 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5603 ErrorFound = true;
5604 } else if (DependFound && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam()) {
5605 Diag(DependFound->getLocStart(),
5606 diag::err_omp_ordered_directive_without_param);
5607 ErrorFound = true;
5608 } else if (TC || Clauses.empty()) {
5609 if (auto *Param = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentOrderedRegionParam()) {
5610 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5611 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5612 << (TC != nullptr);
5613 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5614 ErrorFound = true;
5615 }
5616 }
5617 if ((!AStmt && !DependFound) || ErrorFound)
5618 return StmtError();
5619
5620 if (AStmt) {
5621 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5621, __extension__ __PRETTY_FUNCTION__))
;
5622
5623 getCurFunction()->setHasBranchProtectedScope();
5624 }
5625
5626 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5627}
5628
5629namespace {
5630/// \brief Helper class for checking expression in 'omp atomic [update]'
5631/// construct.
5632class OpenMPAtomicUpdateChecker {
5633 /// \brief Error results for atomic update expressions.
5634 enum ExprAnalysisErrorCode {
5635 /// \brief A statement is not an expression statement.
5636 NotAnExpression,
5637 /// \brief Expression is not builtin binary or unary operation.
5638 NotABinaryOrUnaryExpression,
5639 /// \brief Unary operation is not post-/pre- increment/decrement operation.
5640 NotAnUnaryIncDecExpression,
5641 /// \brief An expression is not of scalar type.
5642 NotAScalarType,
5643 /// \brief A binary operation is not an assignment operation.
5644 NotAnAssignmentOp,
5645 /// \brief RHS part of the binary operation is not a binary expression.
5646 NotABinaryExpression,
5647 /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5648 /// expression.
5649 NotABinaryOperator,
5650 /// \brief RHS binary operation does not have reference to the updated LHS
5651 /// part.
5652 NotAnUpdateExpression,
5653 /// \brief No errors is found.
5654 NoError
5655 };
5656 /// \brief Reference to Sema.
5657 Sema &SemaRef;
5658 /// \brief A location for note diagnostics (when error is found).
5659 SourceLocation NoteLoc;
5660 /// \brief 'x' lvalue part of the source atomic expression.
5661 Expr *X;
5662 /// \brief 'expr' rvalue part of the source atomic expression.
5663 Expr *E;
5664 /// \brief Helper expression of the form
5665 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5666 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5667 Expr *UpdateExpr;
5668 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5669 /// important for non-associative operations.
5670 bool IsXLHSInRHSPart;
5671 BinaryOperatorKind Op;
5672 SourceLocation OpLoc;
5673 /// \brief true if the source expression is a postfix unary operation, false
5674 /// if it is a prefix unary operation.
5675 bool IsPostfixUpdate;
5676
5677public:
5678 OpenMPAtomicUpdateChecker(Sema &SemaRef)
5679 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5680 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5681 /// \brief Check specified statement that it is suitable for 'atomic update'
5682 /// constructs and extract 'x', 'expr' and Operation from the original
5683 /// expression. If DiagId and NoteId == 0, then only check is performed
5684 /// without error notification.
5685 /// \param DiagId Diagnostic which should be emitted if error is found.
5686 /// \param NoteId Diagnostic note for the main error message.
5687 /// \return true if statement is not an update expression, false otherwise.
5688 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5689 /// \brief Return the 'x' lvalue part of the source atomic expression.
5690 Expr *getX() const { return X; }
5691 /// \brief Return the 'expr' rvalue part of the source atomic expression.
5692 Expr *getExpr() const { return E; }
5693 /// \brief Return the update expression used in calculation of the updated
5694 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5695 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5696 Expr *getUpdateExpr() const { return UpdateExpr; }
5697 /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5698 /// false otherwise.
5699 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5700
5701 /// \brief true if the source expression is a postfix unary operation, false
5702 /// if it is a prefix unary operation.
5703 bool isPostfixUpdate() const { return IsPostfixUpdate; }
5704
5705private:
5706 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5707 unsigned NoteId = 0);
5708};
5709} // namespace
5710
5711bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5712 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5713 ExprAnalysisErrorCode ErrorFound = NoError;
5714 SourceLocation ErrorLoc, NoteLoc;
5715 SourceRange ErrorRange, NoteRange;
5716 // Allowed constructs are:
5717 // x = x binop expr;
5718 // x = expr binop x;
5719 if (AtomicBinOp->getOpcode() == BO_Assign) {
5720 X = AtomicBinOp->getLHS();
5721 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5722 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5723 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5724 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5725 AtomicInnerBinOp->isBitwiseOp()) {
5726 Op = AtomicInnerBinOp->getOpcode();
5727 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5728 auto *LHS = AtomicInnerBinOp->getLHS();
5729 auto *RHS = AtomicInnerBinOp->getRHS();
5730 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5731 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5732 /*Canonical=*/true);
5733 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5734 /*Canonical=*/true);
5735 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
5736 /*Canonical=*/true);
5737 if (XId == LHSId) {
5738 E = RHS;
5739 IsXLHSInRHSPart = true;
5740 } else if (XId == RHSId) {
5741 E = LHS;
5742 IsXLHSInRHSPart = false;
5743 } else {
5744 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5745 ErrorRange = AtomicInnerBinOp->getSourceRange();
5746 NoteLoc = X->getExprLoc();
5747 NoteRange = X->getSourceRange();
5748 ErrorFound = NotAnUpdateExpression;
5749 }
5750 } else {
5751 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5752 ErrorRange = AtomicInnerBinOp->getSourceRange();
5753 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5754 NoteRange = SourceRange(NoteLoc, NoteLoc);
5755 ErrorFound = NotABinaryOperator;
5756 }
5757 } else {
5758 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
5759 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
5760 ErrorFound = NotABinaryExpression;
5761 }
5762 } else {
5763 ErrorLoc = AtomicBinOp->getExprLoc();
5764 ErrorRange = AtomicBinOp->getSourceRange();
5765 NoteLoc = AtomicBinOp->getOperatorLoc();
5766 NoteRange = SourceRange(NoteLoc, NoteLoc);
5767 ErrorFound = NotAnAssignmentOp;
5768 }
5769 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5770 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5771 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5772 return true;
5773 } else if (SemaRef.CurContext->isDependentContext())
5774 E = X = UpdateExpr = nullptr;
5775 return ErrorFound != NoError;
5776}
5777
5778bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
5779 unsigned NoteId) {
5780 ExprAnalysisErrorCode ErrorFound = NoError;
5781 SourceLocation ErrorLoc, NoteLoc;
5782 SourceRange ErrorRange, NoteRange;
5783 // Allowed constructs are:
5784 // x++;
5785 // x--;
5786 // ++x;
5787 // --x;
5788 // x binop= expr;
5789 // x = x binop expr;
5790 // x = expr binop x;
5791 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
5792 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5793 if (AtomicBody->getType()->isScalarType() ||
5794 AtomicBody->isInstantiationDependent()) {
5795 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5796 AtomicBody->IgnoreParenImpCasts())) {
5797 // Check for Compound Assignment Operation
5798 Op = BinaryOperator::getOpForCompoundAssignment(
5799 AtomicCompAssignOp->getOpcode());
5800 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5801 E = AtomicCompAssignOp->getRHS();
5802 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5803 IsXLHSInRHSPart = true;
5804 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5805 AtomicBody->IgnoreParenImpCasts())) {
5806 // Check for Binary Operation
5807 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5808 return true;
5809 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5810 AtomicBody->IgnoreParenImpCasts())) {
5811 // Check for Unary Operation
5812 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5813 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5814 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5815 OpLoc = AtomicUnaryOp->getOperatorLoc();
5816 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5817 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
5818 IsXLHSInRHSPart = true;
5819 } else {
5820 ErrorFound = NotAnUnaryIncDecExpression;
5821 ErrorLoc = AtomicUnaryOp->getExprLoc();
5822 ErrorRange = AtomicUnaryOp->getSourceRange();
5823 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5824 NoteRange = SourceRange(NoteLoc, NoteLoc);
5825 }
5826 } else if (!AtomicBody->isInstantiationDependent()) {
5827 ErrorFound = NotABinaryOrUnaryExpression;
5828 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5829 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5830 }
5831 } else {
5832 ErrorFound = NotAScalarType;
5833 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5834 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5835 }
5836 } else {
5837 ErrorFound = NotAnExpression;
5838 NoteLoc = ErrorLoc = S->getLocStart();
5839 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5840 }
5841 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5842 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5843 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5844 return true;
5845 } else if (SemaRef.CurContext->isDependentContext())
5846 E = X = UpdateExpr = nullptr;
5847 if (ErrorFound == NoError && E && X) {
5848 // Build an update expression of form 'OpaqueValueExpr(x) binop
5849 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
5850 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
5851 auto *OVEX = new (SemaRef.getASTContext())
5852 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
5853 auto *OVEExpr = new (SemaRef.getASTContext())
5854 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
5855 auto Update =
5856 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
5857 IsXLHSInRHSPart ? OVEExpr : OVEX);
5858 if (Update.isInvalid())
5859 return true;
5860 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
5861 Sema::AA_Casting);
5862 if (Update.isInvalid())
5863 return true;
5864 UpdateExpr = Update.get();
5865 }
5866 return ErrorFound != NoError;
5867}
5868
5869StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
5870 Stmt *AStmt,
5871 SourceLocation StartLoc,
5872 SourceLocation EndLoc) {
5873 if (!AStmt)
5874 return StmtError();
5875
5876 auto *CS = cast<CapturedStmt>(AStmt);
5877 // 1.2.2 OpenMP Language Terminology
5878 // Structured block - An executable statement with a single entry at the
5879 // top and a single exit at the bottom.
5880 // The point of exit cannot be a branch out of the structured block.
5881 // longjmp() and throw() must not violate the entry/exit criteria.
5882 OpenMPClauseKind AtomicKind = OMPC_unknown;
5883 SourceLocation AtomicKindLoc;
5884 for (auto *C : Clauses) {
5885 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5886 C->getClauseKind() == OMPC_update ||
5887 C->getClauseKind() == OMPC_capture) {
5888 if (AtomicKind != OMPC_unknown) {
5889 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5890 << SourceRange(C->getLocStart(), C->getLocEnd());
5891 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5892 << getOpenMPClauseName(AtomicKind);
5893 } else {
5894 AtomicKind = C->getClauseKind();
5895 AtomicKindLoc = C->getLocStart();
5896 }
5897 }
5898 }
5899
5900 auto Body = CS->getCapturedStmt();
5901 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5902 Body = EWC->getSubExpr();
5903
5904 Expr *X = nullptr;
5905 Expr *V = nullptr;
5906 Expr *E = nullptr;
5907 Expr *UE = nullptr;
5908 bool IsXLHSInRHSPart = false;
5909 bool IsPostfixUpdate = false;
5910 // OpenMP [2.12.6, atomic Construct]
5911 // In the next expressions:
5912 // * x and v (as applicable) are both l-value expressions with scalar type.
5913 // * During the execution of an atomic region, multiple syntactic
5914 // occurrences of x must designate the same storage location.
5915 // * Neither of v and expr (as applicable) may access the storage location
5916 // designated by x.
5917 // * Neither of x and expr (as applicable) may access the storage location
5918 // designated by v.
5919 // * expr is an expression with scalar type.
5920 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5921 // * binop, binop=, ++, and -- are not overloaded operators.
5922 // * The expression x binop expr must be numerically equivalent to x binop
5923 // (expr). This requirement is satisfied if the operators in expr have
5924 // precedence greater than binop, or by using parentheses around expr or
5925 // subexpressions of expr.
5926 // * The expression expr binop x must be numerically equivalent to (expr)
5927 // binop x. This requirement is satisfied if the operators in expr have
5928 // precedence equal to or greater than binop, or by using parentheses around
5929 // expr or subexpressions of expr.
5930 // * For forms that allow multiple occurrences of x, the number of times
5931 // that x is evaluated is unspecified.
5932 if (AtomicKind == OMPC_read) {
5933 enum {
5934 NotAnExpression,
5935 NotAnAssignmentOp,
5936 NotAScalarType,
5937 NotAnLValue,
5938 NoError
5939 } ErrorFound = NoError;
5940 SourceLocation ErrorLoc, NoteLoc;
5941 SourceRange ErrorRange, NoteRange;
5942 // If clause is read:
5943 // v = x;
5944 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5945 auto *AtomicBinOp =
5946 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5947 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5948 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5949 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5950 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5951 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5952 if (!X->isLValue() || !V->isLValue()) {
5953 auto NotLValueExpr = X->isLValue() ? V : X;
5954 ErrorFound = NotAnLValue;
5955 ErrorLoc = AtomicBinOp->getExprLoc();
5956 ErrorRange = AtomicBinOp->getSourceRange();
5957 NoteLoc = NotLValueExpr->getExprLoc();
5958 NoteRange = NotLValueExpr->getSourceRange();
5959 }
5960 } else if (!X->isInstantiationDependent() ||
5961 !V->isInstantiationDependent()) {
5962 auto NotScalarExpr =
5963 (X->isInstantiationDependent() || X->getType()->isScalarType())
5964 ? V
5965 : X;
5966 ErrorFound = NotAScalarType;
5967 ErrorLoc = AtomicBinOp->getExprLoc();
5968 ErrorRange = AtomicBinOp->getSourceRange();
5969 NoteLoc = NotScalarExpr->getExprLoc();
5970 NoteRange = NotScalarExpr->getSourceRange();
5971 }
5972 } else if (!AtomicBody->isInstantiationDependent()) {
5973 ErrorFound = NotAnAssignmentOp;
5974 ErrorLoc = AtomicBody->getExprLoc();
5975 ErrorRange = AtomicBody->getSourceRange();
5976 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5977 : AtomicBody->getExprLoc();
5978 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5979 : AtomicBody->getSourceRange();
5980 }
5981 } else {
5982 ErrorFound = NotAnExpression;
5983 NoteLoc = ErrorLoc = Body->getLocStart();
5984 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5985 }
5986 if (ErrorFound != NoError) {
5987 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5988 << ErrorRange;
5989 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5990 << NoteRange;
5991 return StmtError();
5992 } else if (CurContext->isDependentContext())
5993 V = X = nullptr;
5994 } else if (AtomicKind == OMPC_write) {
5995 enum {
5996 NotAnExpression,
5997 NotAnAssignmentOp,
5998 NotAScalarType,
5999 NotAnLValue,
6000 NoError
6001 } ErrorFound = NoError;
6002 SourceLocation ErrorLoc, NoteLoc;
6003 SourceRange ErrorRange, NoteRange;
6004 // If clause is write:
6005 // x = expr;
6006 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6007 auto *AtomicBinOp =
6008 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6009 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6010 X = AtomicBinOp->getLHS();
6011 E = AtomicBinOp->getRHS();
6012 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6013 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6014 if (!X->isLValue()) {
6015 ErrorFound = NotAnLValue;
6016 ErrorLoc = AtomicBinOp->getExprLoc();
6017 ErrorRange = AtomicBinOp->getSourceRange();
6018 NoteLoc = X->getExprLoc();
6019 NoteRange = X->getSourceRange();
6020 }
6021 } else if (!X->isInstantiationDependent() ||
6022 !E->isInstantiationDependent()) {
6023 auto NotScalarExpr =
6024 (X->isInstantiationDependent() || X->getType()->isScalarType())
6025 ? E
6026 : X;
6027 ErrorFound = NotAScalarType;
6028 ErrorLoc = AtomicBinOp->getExprLoc();
6029 ErrorRange = AtomicBinOp->getSourceRange();
6030 NoteLoc = NotScalarExpr->getExprLoc();
6031 NoteRange = NotScalarExpr->getSourceRange();
6032 }
6033 } else if (!AtomicBody->isInstantiationDependent()) {
6034 ErrorFound = NotAnAssignmentOp;
6035 ErrorLoc = AtomicBody->getExprLoc();
6036 ErrorRange = AtomicBody->getSourceRange();
6037 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6038 : AtomicBody->getExprLoc();
6039 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6040 : AtomicBody->getSourceRange();
6041 }
6042 } else {
6043 ErrorFound = NotAnExpression;
6044 NoteLoc = ErrorLoc = Body->getLocStart();
6045 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6046 }
6047 if (ErrorFound != NoError) {
6048 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6049 << ErrorRange;
6050 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6051 << NoteRange;
6052 return StmtError();
6053 } else if (CurContext->isDependentContext())
6054 E = X = nullptr;
6055 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6056 // If clause is update:
6057 // x++;
6058 // x--;
6059 // ++x;
6060 // --x;
6061 // x binop= expr;
6062 // x = x binop expr;
6063 // x = expr binop x;
6064 OpenMPAtomicUpdateChecker Checker(*this);
6065 if (Checker.checkStatement(
6066 Body, (AtomicKind == OMPC_update)
6067 ? diag::err_omp_atomic_update_not_expression_statement
6068 : diag::err_omp_atomic_not_expression_statement,
6069 diag::note_omp_atomic_update))
6070 return StmtError();
6071 if (!CurContext->isDependentContext()) {
6072 E = Checker.getExpr();
6073 X = Checker.getX();
6074 UE = Checker.getUpdateExpr();
6075 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6076 }
6077 } else if (AtomicKind == OMPC_capture) {
6078 enum {
6079 NotAnAssignmentOp,
6080 NotACompoundStatement,
6081 NotTwoSubstatements,
6082 NotASpecificExpression,
6083 NoError
6084 } ErrorFound = NoError;
6085 SourceLocation ErrorLoc, NoteLoc;
6086 SourceRange ErrorRange, NoteRange;
6087 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6088 // If clause is a capture:
6089 // v = x++;
6090 // v = x--;
6091 // v = ++x;
6092 // v = --x;
6093 // v = x binop= expr;
6094 // v = x = x binop expr;
6095 // v = x = expr binop x;
6096 auto *AtomicBinOp =
6097 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6098 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6099 V = AtomicBinOp->getLHS();
6100 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6101 OpenMPAtomicUpdateChecker Checker(*this);
6102 if (Checker.checkStatement(
6103 Body, diag::err_omp_atomic_capture_not_expression_statement,
6104 diag::note_omp_atomic_update))
6105 return StmtError();
6106 E = Checker.getExpr();
6107 X = Checker.getX();
6108 UE = Checker.getUpdateExpr();
6109 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6110 IsPostfixUpdate = Checker.isPostfixUpdate();
6111 } else if (!AtomicBody->isInstantiationDependent()) {
6112 ErrorLoc = AtomicBody->getExprLoc();
6113 ErrorRange = AtomicBody->getSourceRange();
6114 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6115 : AtomicBody->getExprLoc();
6116 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6117 : AtomicBody->getSourceRange();
6118 ErrorFound = NotAnAssignmentOp;
6119 }
6120 if (ErrorFound != NoError) {
6121 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6122 << ErrorRange;
6123 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6124 return StmtError();
6125 } else if (CurContext->isDependentContext()) {
6126 UE = V = E = X = nullptr;
6127 }
6128 } else {
6129 // If clause is a capture:
6130 // { v = x; x = expr; }
6131 // { v = x; x++; }
6132 // { v = x; x--; }
6133 // { v = x; ++x; }
6134 // { v = x; --x; }
6135 // { v = x; x binop= expr; }
6136 // { v = x; x = x binop expr; }
6137 // { v = x; x = expr binop x; }
6138 // { x++; v = x; }
6139 // { x--; v = x; }
6140 // { ++x; v = x; }
6141 // { --x; v = x; }
6142 // { x binop= expr; v = x; }
6143 // { x = x binop expr; v = x; }
6144 // { x = expr binop x; v = x; }
6145 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6146 // Check that this is { expr1; expr2; }
6147 if (CS->size() == 2) {
6148 auto *First = CS->body_front();
6149 auto *Second = CS->body_back();
6150 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6151 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6152 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6153 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6154 // Need to find what subexpression is 'v' and what is 'x'.
6155 OpenMPAtomicUpdateChecker Checker(*this);
6156 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6157 BinaryOperator *BinOp = nullptr;
6158 if (IsUpdateExprFound) {
6159 BinOp = dyn_cast<BinaryOperator>(First);
6160 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6161 }
6162 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6163 // { v = x; x++; }
6164 // { v = x; x--; }
6165 // { v = x; ++x; }
6166 // { v = x; --x; }
6167 // { v = x; x binop= expr; }
6168 // { v = x; x = x binop expr; }
6169 // { v = x; x = expr binop x; }
6170 // Check that the first expression has form v = x.
6171 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6172 llvm::FoldingSetNodeID XId, PossibleXId;
6173 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6174 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6175 IsUpdateExprFound = XId == PossibleXId;
6176 if (IsUpdateExprFound) {
6177 V = BinOp->getLHS();
6178 X = Checker.getX();
6179 E = Checker.getExpr();
6180 UE = Checker.getUpdateExpr();
6181 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6182 IsPostfixUpdate = true;
6183 }
6184 }
6185 if (!IsUpdateExprFound) {
6186 IsUpdateExprFound = !Checker.checkStatement(First);
6187 BinOp = nullptr;
6188 if (IsUpdateExprFound) {
6189 BinOp = dyn_cast<BinaryOperator>(Second);
6190 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6191 }
6192 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6193 // { x++; v = x; }
6194 // { x--; v = x; }
6195 // { ++x; v = x; }
6196 // { --x; v = x; }
6197 // { x binop= expr; v = x; }
6198 // { x = x binop expr; v = x; }
6199 // { x = expr binop x; v = x; }
6200 // Check that the second expression has form v = x.
6201 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6202 llvm::FoldingSetNodeID XId, PossibleXId;
6203 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6204 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6205 IsUpdateExprFound = XId == PossibleXId;
6206 if (IsUpdateExprFound) {
6207 V = BinOp->getLHS();
6208 X = Checker.getX();
6209 E = Checker.getExpr();
6210 UE = Checker.getUpdateExpr();
6211 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6212 IsPostfixUpdate = false;
6213 }
6214 }
6215 }
6216 if (!IsUpdateExprFound) {
6217 // { v = x; x = expr; }
6218 auto *FirstExpr = dyn_cast<Expr>(First);
6219 auto *SecondExpr = dyn_cast<Expr>(Second);
6220 if (!FirstExpr || !SecondExpr ||
6221 !(FirstExpr->isInstantiationDependent() ||
6222 SecondExpr->isInstantiationDependent())) {
6223 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6224 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6225 ErrorFound = NotAnAssignmentOp;
6226 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6227 : First->getLocStart();
6228 NoteRange = ErrorRange = FirstBinOp
6229 ? FirstBinOp->getSourceRange()
6230 : SourceRange(ErrorLoc, ErrorLoc);
6231 } else {
6232 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6233 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6234 ErrorFound = NotAnAssignmentOp;
6235 NoteLoc = ErrorLoc = SecondBinOp
6236 ? SecondBinOp->getOperatorLoc()
6237 : Second->getLocStart();
6238 NoteRange = ErrorRange =
6239 SecondBinOp ? SecondBinOp->getSourceRange()
6240 : SourceRange(ErrorLoc, ErrorLoc);
6241 } else {
6242 auto *PossibleXRHSInFirst =
6243 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6244 auto *PossibleXLHSInSecond =
6245 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6246 llvm::FoldingSetNodeID X1Id, X2Id;
6247 PossibleXRHSInFirst->Profile(X1Id, Context,
6248 /*Canonical=*/true);
6249 PossibleXLHSInSecond->Profile(X2Id, Context,
6250 /*Canonical=*/true);
6251 IsUpdateExprFound = X1Id == X2Id;
6252 if (IsUpdateExprFound) {
6253 V = FirstBinOp->getLHS();
6254 X = SecondBinOp->getLHS();
6255 E = SecondBinOp->getRHS();
6256 UE = nullptr;
6257 IsXLHSInRHSPart = false;
6258 IsPostfixUpdate = true;
6259 } else {
6260 ErrorFound = NotASpecificExpression;
6261 ErrorLoc = FirstBinOp->getExprLoc();
6262 ErrorRange = FirstBinOp->getSourceRange();
6263 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6264 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6265 }
6266 }
6267 }
6268 }
6269 }
6270 } else {
6271 NoteLoc = ErrorLoc = Body->getLocStart();
6272 NoteRange = ErrorRange =
6273 SourceRange(Body->getLocStart(), Body->getLocStart());
6274 ErrorFound = NotTwoSubstatements;
6275 }
6276 } else {
6277 NoteLoc = ErrorLoc = Body->getLocStart();
6278 NoteRange = ErrorRange =
6279 SourceRange(Body->getLocStart(), Body->getLocStart());
6280 ErrorFound = NotACompoundStatement;
6281 }
6282 if (ErrorFound != NoError) {
6283 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6284 << ErrorRange;
6285 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6286 return StmtError();
6287 } else if (CurContext->isDependentContext()) {
6288 UE = V = E = X = nullptr;
6289 }
6290 }
6291 }
6292
6293 getCurFunction()->setHasBranchProtectedScope();
6294
6295 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6296 X, V, E, UE, IsXLHSInRHSPart,
6297 IsPostfixUpdate);
6298}
6299
6300StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6301 Stmt *AStmt,
6302 SourceLocation StartLoc,
6303 SourceLocation EndLoc) {
6304 if (!AStmt)
6305 return StmtError();
6306
6307 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6308 // 1.2.2 OpenMP Language Terminology
6309 // Structured block - An executable statement with a single entry at the
6310 // top and a single exit at the bottom.
6311 // The point of exit cannot be a branch out of the structured block.
6312 // longjmp() and throw() must not violate the entry/exit criteria.
6313 CS->getCapturedDecl()->setNothrow();
6314
6315 // OpenMP [2.16, Nesting of Regions]
6316 // If specified, a teams construct must be contained within a target
6317 // construct. That target construct must contain no statements or directives
6318 // outside of the teams construct.
6319 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasInnerTeamsRegion()) {
6320 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
6321 bool OMPTeamsFound = true;
6322 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6323 auto I = CS->body_begin();
6324 while (I != CS->body_end()) {
6325 auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6326 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6327 OMPTeamsFound = false;
6328 break;
6329 }
6330 ++I;
6331 }
6332 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6332, __extension__ __PRETTY_FUNCTION__))
;
6333 S = *I;
6334 } else {
6335 auto *OED = dyn_cast<OMPExecutableDirective>(S);
6336 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6337 }
6338 if (!OMPTeamsFound) {
6339 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6340 Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getInnerTeamsRegionLoc(),
6341 diag::note_omp_nested_teams_construct_here);
6342 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6343 << isa<OMPExecutableDirective>(S);
6344 return StmtError();
6345 }
6346 }
6347
6348 getCurFunction()->setHasBranchProtectedScope();
6349
6350 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6351}
6352
6353StmtResult
6354Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
6355 Stmt *AStmt, SourceLocation StartLoc,
6356 SourceLocation EndLoc) {
6357 if (!AStmt)
6358 return StmtError();
6359
6360 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6361 // 1.2.2 OpenMP Language Terminology
6362 // Structured block - An executable statement with a single entry at the
6363 // top and a single exit at the bottom.
6364 // The point of exit cannot be a branch out of the structured block.
6365 // longjmp() and throw() must not violate the entry/exit criteria.
6366 CS->getCapturedDecl()->setNothrow();
6367
6368 getCurFunction()->setHasBranchProtectedScope();
6369
6370 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6371 AStmt);
6372}
6373
6374StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
6375 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6376 SourceLocation EndLoc,
6377 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6378 if (!AStmt)
6379 return StmtError();
6380
6381 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6382 // 1.2.2 OpenMP Language Terminology
6383 // Structured block - An executable statement with a single entry at the
6384 // top and a single exit at the bottom.
6385 // The point of exit cannot be a branch out of the structured block.
6386 // longjmp() and throw() must not violate the entry/exit criteria.
6387 CS->getCapturedDecl()->setNothrow();
6388 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6389 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6390 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6391 // 1.2.2 OpenMP Language Terminology
6392 // Structured block - An executable statement with a single entry at the
6393 // top and a single exit at the bottom.
6394 // The point of exit cannot be a branch out of the structured block.
6395 // longjmp() and throw() must not violate the entry/exit criteria.
6396 CS->getCapturedDecl()->setNothrow();
6397 }
6398
6399 OMPLoopDirective::HelperExprs B;
6400 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6401 // define the nested loops number.
6402 unsigned NestedLoopCount =
6403 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6404 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6405 VarsWithImplicitDSA, B);
6406 if (NestedLoopCount == 0)
6407 return StmtError();
6408
6409 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6410, __extension__ __PRETTY_FUNCTION__))
6410 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6410, __extension__ __PRETTY_FUNCTION__))
;
6411
6412 if (!CurContext->isDependentContext()) {
6413 // Finalize the clauses that need pre-built expressions for CodeGen.
6414 for (auto C : Clauses) {
6415 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6416 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6417 B.NumIterations, *this, CurScope,
6418 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6419 return StmtError();
6420 }
6421 }
6422
6423 getCurFunction()->setHasBranchProtectedScope();
6424 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6425 NestedLoopCount, Clauses, AStmt,
6426 B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6427}
6428
6429/// Check for existence of a map clause in the list of clauses.
6430static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6431 const OpenMPClauseKind K) {
6432 return llvm::any_of(
6433 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6434}
6435
6436template <typename... Params>
6437static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
6438 const Params... ClauseTypes) {
6439 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6440}
6441
6442StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
6443 Stmt *AStmt,
6444 SourceLocation StartLoc,
6445 SourceLocation EndLoc) {
6446 if (!AStmt)
6447 return StmtError();
6448
6449 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6449, __extension__ __PRETTY_FUNCTION__))
;
6450
6451 // OpenMP [2.10.1, Restrictions, p. 97]
6452 // At least one map clause must appear on the directive.
6453 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6454 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6455 << "'map' or 'use_device_ptr'"
6456 << getOpenMPDirectiveName(OMPD_target_data);
6457 return StmtError();
6458 }
6459
6460 getCurFunction()->setHasBranchProtectedScope();
6461
6462 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6463 AStmt);
6464}
6465
6466StmtResult
6467Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
6468 SourceLocation StartLoc,
6469 SourceLocation EndLoc, Stmt *AStmt) {
6470 if (!AStmt)
6471 return StmtError();
6472
6473 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6474 // 1.2.2 OpenMP Language Terminology
6475 // Structured block - An executable statement with a single entry at the
6476 // top and a single exit at the bottom.
6477 // The point of exit cannot be a branch out of the structured block.
6478 // longjmp() and throw() must not violate the entry/exit criteria.
6479 CS->getCapturedDecl()->setNothrow();
6480 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6481 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6482 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6483 // 1.2.2 OpenMP Language Terminology
6484 // Structured block - An executable statement with a single entry at the
6485 // top and a single exit at the bottom.
6486 // The point of exit cannot be a branch out of the structured block.
6487 // longjmp() and throw() must not violate the entry/exit criteria.
6488 CS->getCapturedDecl()->setNothrow();
6489 }
6490
6491 // OpenMP [2.10.2, Restrictions, p. 99]
6492 // At least one map clause must appear on the directive.
6493 if (!hasClauses(Clauses, OMPC_map)) {
6494 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6495 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6496 return StmtError();
6497 }
6498
6499 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6500 AStmt);
6501}
6502
6503StmtResult
6504Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
6505 SourceLocation StartLoc,
6506 SourceLocation EndLoc, Stmt *AStmt) {
6507 if (!AStmt)
6508 return StmtError();
6509
6510 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6511 // 1.2.2 OpenMP Language Terminology
6512 // Structured block - An executable statement with a single entry at the
6513 // top and a single exit at the bottom.
6514 // The point of exit cannot be a branch out of the structured block.
6515 // longjmp() and throw() must not violate the entry/exit criteria.
6516 CS->getCapturedDecl()->setNothrow();
6517 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6518 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6519 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6520 // 1.2.2 OpenMP Language Terminology
6521 // Structured block - An executable statement with a single entry at the
6522 // top and a single exit at the bottom.
6523 // The point of exit cannot be a branch out of the structured block.
6524 // longjmp() and throw() must not violate the entry/exit criteria.
6525 CS->getCapturedDecl()->setNothrow();
6526 }
6527
6528 // OpenMP [2.10.3, Restrictions, p. 102]
6529 // At least one map clause must appear on the directive.
6530 if (!hasClauses(Clauses, OMPC_map)) {
6531 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6532 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6533 return StmtError();
6534 }
6535
6536 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6537 AStmt);
6538}
6539
6540StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
6541 SourceLocation StartLoc,
6542 SourceLocation EndLoc,
6543 Stmt *AStmt) {
6544 if (!AStmt)
6545 return StmtError();
6546
6547 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6548 // 1.2.2 OpenMP Language Terminology
6549 // Structured block - An executable statement with a single entry at the
6550 // top and a single exit at the bottom.
6551 // The point of exit cannot be a branch out of the structured block.
6552 // longjmp() and throw() must not violate the entry/exit criteria.
6553 CS->getCapturedDecl()->setNothrow();
6554 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6555 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6556 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6557 // 1.2.2 OpenMP Language Terminology
6558 // Structured block - An executable statement with a single entry at the
6559 // top and a single exit at the bottom.
6560 // The point of exit cannot be a branch out of the structured block.
6561 // longjmp() and throw() must not violate the entry/exit criteria.
6562 CS->getCapturedDecl()->setNothrow();
6563 }
6564
6565 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6566 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6567 return StmtError();
6568 }
6569 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6570 AStmt);
6571}
6572
6573StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
6574 Stmt *AStmt, SourceLocation StartLoc,
6575 SourceLocation EndLoc) {
6576 if (!AStmt)
6577 return StmtError();
6578
6579 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6580 // 1.2.2 OpenMP Language Terminology
6581 // Structured block - An executable statement with a single entry at the
6582 // top and a single exit at the bottom.
6583 // The point of exit cannot be a branch out of the structured block.
6584 // longjmp() and throw() must not violate the entry/exit criteria.
6585 CS->getCapturedDecl()->setNothrow();
6586
6587 getCurFunction()->setHasBranchProtectedScope();
6588
6589 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
6590
6591 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6592}
6593
6594StmtResult
6595Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
6596 SourceLocation EndLoc,
6597 OpenMPDirectiveKind CancelRegion) {
6598 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
6599 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6600 return StmtError();
6601 }
6602 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
6603 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6604 return StmtError();
6605 }
6606 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6607 CancelRegion);
6608}
6609
6610StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
6611 SourceLocation StartLoc,
6612 SourceLocation EndLoc,
6613 OpenMPDirectiveKind CancelRegion) {
6614 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentNowaitRegion()) {
6615 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6616 return StmtError();
6617 }
6618 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isParentOrderedRegion()) {
6619 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6620 return StmtError();
6621 }
6622 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(/*Cancel=*/true);
6623 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6624 CancelRegion);
6625}
6626
6627static bool checkGrainsizeNumTasksClauses(Sema &S,
6628 ArrayRef<OMPClause *> Clauses) {
6629 OMPClause *PrevClause = nullptr;
6630 bool ErrorFound = false;
6631 for (auto *C : Clauses) {
6632 if (C->getClauseKind() == OMPC_grainsize ||
6633 C->getClauseKind() == OMPC_num_tasks) {
6634 if (!PrevClause)
6635 PrevClause = C;
6636 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6637 S.Diag(C->getLocStart(),
6638 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6639 << getOpenMPClauseName(C->getClauseKind())
6640 << getOpenMPClauseName(PrevClause->getClauseKind());
6641 S.Diag(PrevClause->getLocStart(),
6642 diag::note_omp_previous_grainsize_num_tasks)
6643 << getOpenMPClauseName(PrevClause->getClauseKind());
6644 ErrorFound = true;
6645 }
6646 }
6647 }
6648 return ErrorFound;
6649}
6650
6651static bool checkReductionClauseWithNogroup(Sema &S,
6652 ArrayRef<OMPClause *> Clauses) {
6653 OMPClause *ReductionClause = nullptr;
6654 OMPClause *NogroupClause = nullptr;
6655 for (auto *C : Clauses) {
6656 if (C->getClauseKind() == OMPC_reduction) {
6657 ReductionClause = C;
6658 if (NogroupClause)
6659 break;
6660 continue;
6661 }
6662 if (C->getClauseKind() == OMPC_nogroup) {
6663 NogroupClause = C;
6664 if (ReductionClause)
6665 break;
6666 continue;
6667 }
6668 }
6669 if (ReductionClause && NogroupClause) {
6670 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
6671 << SourceRange(NogroupClause->getLocStart(),
6672 NogroupClause->getLocEnd());
6673 return true;
6674 }
6675 return false;
6676}
6677
6678StmtResult Sema::ActOnOpenMPTaskLoopDirective(
6679 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6680 SourceLocation EndLoc,
6681 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6682 if (!AStmt)
6683 return StmtError();
6684
6685 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6685, __extension__ __PRETTY_FUNCTION__))
;
6686 OMPLoopDirective::HelperExprs B;
6687 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6688 // define the nested loops number.
6689 unsigned NestedLoopCount =
6690 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6691 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6692 VarsWithImplicitDSA, B);
6693 if (NestedLoopCount == 0)
6694 return StmtError();
6695
6696 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6697, __extension__ __PRETTY_FUNCTION__))
6697 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6697, __extension__ __PRETTY_FUNCTION__))
;
6698
6699 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6700 // The grainsize clause and num_tasks clause are mutually exclusive and may
6701 // not appear on the same taskloop directive.
6702 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6703 return StmtError();
6704 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6705 // If a reduction clause is present on the taskloop directive, the nogroup
6706 // clause must not be specified.
6707 if (checkReductionClauseWithNogroup(*this, Clauses))
6708 return StmtError();
6709
6710 getCurFunction()->setHasBranchProtectedScope();
6711 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6712 NestedLoopCount, Clauses, AStmt, B);
6713}
6714
6715StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
6716 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6717 SourceLocation EndLoc,
6718 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6719 if (!AStmt)
6720 return StmtError();
6721
6722 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6722, __extension__ __PRETTY_FUNCTION__))
;
6723 OMPLoopDirective::HelperExprs B;
6724 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6725 // define the nested loops number.
6726 unsigned NestedLoopCount =
6727 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
6728 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6729 VarsWithImplicitDSA, B);
6730 if (NestedLoopCount == 0)
6731 return StmtError();
6732
6733 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6734, __extension__ __PRETTY_FUNCTION__))
6734 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6734, __extension__ __PRETTY_FUNCTION__))
;
6735
6736 if (!CurContext->isDependentContext()) {
6737 // Finalize the clauses that need pre-built expressions for CodeGen.
6738 for (auto C : Clauses) {
6739 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6740 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6741 B.NumIterations, *this, CurScope,
6742 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6743 return StmtError();
6744 }
6745 }
6746
6747 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6748 // The grainsize clause and num_tasks clause are mutually exclusive and may
6749 // not appear on the same taskloop directive.
6750 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6751 return StmtError();
6752 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6753 // If a reduction clause is present on the taskloop directive, the nogroup
6754 // clause must not be specified.
6755 if (checkReductionClauseWithNogroup(*this, Clauses))
6756 return StmtError();
6757 if (checkSimdlenSafelenSpecified(*this, Clauses))
6758 return StmtError();
6759
6760 getCurFunction()->setHasBranchProtectedScope();
6761 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
6762 NestedLoopCount, Clauses, AStmt, B);
6763}
6764
6765StmtResult Sema::ActOnOpenMPDistributeDirective(
6766 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6767 SourceLocation EndLoc,
6768 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6769 if (!AStmt)
6770 return StmtError();
6771
6772 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6772, __extension__ __PRETTY_FUNCTION__))
;
6773 OMPLoopDirective::HelperExprs B;
6774 // In presence of clause 'collapse' with number of loops, it will
6775 // define the nested loops number.
6776 unsigned NestedLoopCount =
6777 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
6778 nullptr /*ordered not a clause on distribute*/, AStmt,
6779 *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
6780 if (NestedLoopCount == 0)
6781 return StmtError();
6782
6783 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6784, __extension__ __PRETTY_FUNCTION__))
6784 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6784, __extension__ __PRETTY_FUNCTION__))
;
6785
6786 getCurFunction()->setHasBranchProtectedScope();
6787 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
6788 NestedLoopCount, Clauses, AStmt, B);
6789}
6790
6791StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
6792 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6793 SourceLocation EndLoc,
6794 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6795 if (!AStmt)
6796 return StmtError();
6797
6798 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6799 // 1.2.2 OpenMP Language Terminology
6800 // Structured block - An executable statement with a single entry at the
6801 // top and a single exit at the bottom.
6802 // The point of exit cannot be a branch out of the structured block.
6803 // longjmp() and throw() must not violate the entry/exit criteria.
6804 CS->getCapturedDecl()->setNothrow();
6805 for (int ThisCaptureLevel =
6806 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6807 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6808 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6809 // 1.2.2 OpenMP Language Terminology
6810 // Structured block - An executable statement with a single entry at the
6811 // top and a single exit at the bottom.
6812 // The point of exit cannot be a branch out of the structured block.
6813 // longjmp() and throw() must not violate the entry/exit criteria.
6814 CS->getCapturedDecl()->setNothrow();
6815 }
6816
6817 OMPLoopDirective::HelperExprs B;
6818 // In presence of clause 'collapse' with number of loops, it will
6819 // define the nested loops number.
6820 unsigned NestedLoopCount = CheckOpenMPLoop(
6821 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
6822 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6823 VarsWithImplicitDSA, B);
6824 if (NestedLoopCount == 0)
6825 return StmtError();
6826
6827 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6828, __extension__ __PRETTY_FUNCTION__))
6828 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6828, __extension__ __PRETTY_FUNCTION__))
;
6829
6830 getCurFunction()->setHasBranchProtectedScope();
6831 return OMPDistributeParallelForDirective::Create(
6832 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6833 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
6834}
6835
6836StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
6837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6838 SourceLocation EndLoc,
6839 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6840 if (!AStmt)
6841 return StmtError();
6842
6843 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6844 // 1.2.2 OpenMP Language Terminology
6845 // Structured block - An executable statement with a single entry at the
6846 // top and a single exit at the bottom.
6847 // The point of exit cannot be a branch out of the structured block.
6848 // longjmp() and throw() must not violate the entry/exit criteria.
6849 CS->getCapturedDecl()->setNothrow();
6850 for (int ThisCaptureLevel =
6851 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6852 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6853 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6854 // 1.2.2 OpenMP Language Terminology
6855 // Structured block - An executable statement with a single entry at the
6856 // top and a single exit at the bottom.
6857 // The point of exit cannot be a branch out of the structured block.
6858 // longjmp() and throw() must not violate the entry/exit criteria.
6859 CS->getCapturedDecl()->setNothrow();
6860 }
6861
6862 OMPLoopDirective::HelperExprs B;
6863 // In presence of clause 'collapse' with number of loops, it will
6864 // define the nested loops number.
6865 unsigned NestedLoopCount = CheckOpenMPLoop(
6866 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
6867 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6868 VarsWithImplicitDSA, B);
6869 if (NestedLoopCount == 0)
6870 return StmtError();
6871
6872 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6873, __extension__ __PRETTY_FUNCTION__))
6873 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6873, __extension__ __PRETTY_FUNCTION__))
;
6874
6875 if (!CurContext->isDependentContext()) {
6876 // Finalize the clauses that need pre-built expressions for CodeGen.
6877 for (auto C : Clauses) {
6878 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6879 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6880 B.NumIterations, *this, CurScope,
6881 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6882 return StmtError();
6883 }
6884 }
6885
6886 if (checkSimdlenSafelenSpecified(*this, Clauses))
6887 return StmtError();
6888
6889 getCurFunction()->setHasBranchProtectedScope();
6890 return OMPDistributeParallelForSimdDirective::Create(
6891 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6892}
6893
6894StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
6895 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6896 SourceLocation EndLoc,
6897 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6898 if (!AStmt)
6899 return StmtError();
6900
6901 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6902 // 1.2.2 OpenMP Language Terminology
6903 // Structured block - An executable statement with a single entry at the
6904 // top and a single exit at the bottom.
6905 // The point of exit cannot be a branch out of the structured block.
6906 // longjmp() and throw() must not violate the entry/exit criteria.
6907 CS->getCapturedDecl()->setNothrow();
6908 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
6909 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6910 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6911 // 1.2.2 OpenMP Language Terminology
6912 // Structured block - An executable statement with a single entry at the
6913 // top and a single exit at the bottom.
6914 // The point of exit cannot be a branch out of the structured block.
6915 // longjmp() and throw() must not violate the entry/exit criteria.
6916 CS->getCapturedDecl()->setNothrow();
6917 }
6918
6919 OMPLoopDirective::HelperExprs B;
6920 // In presence of clause 'collapse' with number of loops, it will
6921 // define the nested loops number.
6922 unsigned NestedLoopCount =
6923 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
6924 nullptr /*ordered not a clause on distribute*/, CS, *this,
6925 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
6926 if (NestedLoopCount == 0)
6927 return StmtError();
6928
6929 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6930, __extension__ __PRETTY_FUNCTION__))
6930 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6930, __extension__ __PRETTY_FUNCTION__))
;
6931
6932 if (!CurContext->isDependentContext()) {
6933 // Finalize the clauses that need pre-built expressions for CodeGen.
6934 for (auto C : Clauses) {
6935 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6936 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6937 B.NumIterations, *this, CurScope,
6938 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6939 return StmtError();
6940 }
6941 }
6942
6943 if (checkSimdlenSafelenSpecified(*this, Clauses))
6944 return StmtError();
6945
6946 getCurFunction()->setHasBranchProtectedScope();
6947 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
6948 NestedLoopCount, Clauses, AStmt, B);
6949}
6950
6951StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
6952 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6953 SourceLocation EndLoc,
6954 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6955 if (!AStmt)
6956 return StmtError();
6957
6958 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6959 // 1.2.2 OpenMP Language Terminology
6960 // Structured block - An executable statement with a single entry at the
6961 // top and a single exit at the bottom.
6962 // The point of exit cannot be a branch out of the structured block.
6963 // longjmp() and throw() must not violate the entry/exit criteria.
6964 CS->getCapturedDecl()->setNothrow();
6965 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6966 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6967 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6968 // 1.2.2 OpenMP Language Terminology
6969 // Structured block - An executable statement with a single entry at the
6970 // top and a single exit at the bottom.
6971 // The point of exit cannot be a branch out of the structured block.
6972 // longjmp() and throw() must not violate the entry/exit criteria.
6973 CS->getCapturedDecl()->setNothrow();
6974 }
6975
6976 OMPLoopDirective::HelperExprs B;
6977 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6978 // define the nested loops number.
6979 unsigned NestedLoopCount = CheckOpenMPLoop(
6980 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
6981 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
6982 VarsWithImplicitDSA, B);
6983 if (NestedLoopCount == 0)
6984 return StmtError();
6985
6986 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6987, __extension__ __PRETTY_FUNCTION__))
6987 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 6987, __extension__ __PRETTY_FUNCTION__))
;
6988
6989 if (!CurContext->isDependentContext()) {
6990 // Finalize the clauses that need pre-built expressions for CodeGen.
6991 for (auto C : Clauses) {
6992 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6993 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6994 B.NumIterations, *this, CurScope,
6995 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
6996 return StmtError();
6997 }
6998 }
6999 if (checkSimdlenSafelenSpecified(*this, Clauses))
7000 return StmtError();
7001
7002 getCurFunction()->setHasBranchProtectedScope();
7003 return OMPTargetParallelForSimdDirective::Create(
7004 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7005}
7006
7007StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7008 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7009 SourceLocation EndLoc,
7010 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7011 if (!AStmt)
7012 return StmtError();
7013
7014 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7015 // 1.2.2 OpenMP Language Terminology
7016 // Structured block - An executable statement with a single entry at the
7017 // top and a single exit at the bottom.
7018 // The point of exit cannot be a branch out of the structured block.
7019 // longjmp() and throw() must not violate the entry/exit criteria.
7020 CS->getCapturedDecl()->setNothrow();
7021 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7022 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7023 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7024 // 1.2.2 OpenMP Language Terminology
7025 // Structured block - An executable statement with a single entry at the
7026 // top and a single exit at the bottom.
7027 // The point of exit cannot be a branch out of the structured block.
7028 // longjmp() and throw() must not violate the entry/exit criteria.
7029 CS->getCapturedDecl()->setNothrow();
7030 }
7031
7032 OMPLoopDirective::HelperExprs B;
7033 // In presence of clause 'collapse' with number of loops, it will define the
7034 // nested loops number.
7035 unsigned NestedLoopCount =
7036 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7037 getOrderedNumberExpr(Clauses), CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7038 VarsWithImplicitDSA, B);
7039 if (NestedLoopCount == 0)
7040 return StmtError();
7041
7042 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7043, __extension__ __PRETTY_FUNCTION__))
7043 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7043, __extension__ __PRETTY_FUNCTION__))
;
7044
7045 if (!CurContext->isDependentContext()) {
7046 // Finalize the clauses that need pre-built expressions for CodeGen.
7047 for (auto C : Clauses) {
7048 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7049 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7050 B.NumIterations, *this, CurScope,
7051 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7052 return StmtError();
7053 }
7054 }
7055
7056 if (checkSimdlenSafelenSpecified(*this, Clauses))
7057 return StmtError();
7058
7059 getCurFunction()->setHasBranchProtectedScope();
7060 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7061 NestedLoopCount, Clauses, AStmt, B);
7062}
7063
7064StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7065 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7066 SourceLocation EndLoc,
7067 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7068 if (!AStmt)
7069 return StmtError();
7070
7071 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7072 // 1.2.2 OpenMP Language Terminology
7073 // Structured block - An executable statement with a single entry at the
7074 // top and a single exit at the bottom.
7075 // The point of exit cannot be a branch out of the structured block.
7076 // longjmp() and throw() must not violate the entry/exit criteria.
7077 CS->getCapturedDecl()->setNothrow();
7078 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7079 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7080 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7081 // 1.2.2 OpenMP Language Terminology
7082 // Structured block - An executable statement with a single entry at the
7083 // top and a single exit at the bottom.
7084 // The point of exit cannot be a branch out of the structured block.
7085 // longjmp() and throw() must not violate the entry/exit criteria.
7086 CS->getCapturedDecl()->setNothrow();
7087 }
7088
7089 OMPLoopDirective::HelperExprs B;
7090 // In presence of clause 'collapse' with number of loops, it will
7091 // define the nested loops number.
7092 unsigned NestedLoopCount =
7093 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7094 nullptr /*ordered not a clause on distribute*/, CS, *this,
7095 *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
7096 if (NestedLoopCount == 0)
7097 return StmtError();
7098
7099 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7100, __extension__ __PRETTY_FUNCTION__))
7100 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7100, __extension__ __PRETTY_FUNCTION__))
;
7101
7102 getCurFunction()->setHasBranchProtectedScope();
7103
7104 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7105
7106 return OMPTeamsDistributeDirective::Create(
7107 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7108}
7109
7110StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7111 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7112 SourceLocation EndLoc,
7113 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7114 if (!AStmt)
7115 return StmtError();
7116
7117 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7118 // 1.2.2 OpenMP Language Terminology
7119 // Structured block - An executable statement with a single entry at the
7120 // top and a single exit at the bottom.
7121 // The point of exit cannot be a branch out of the structured block.
7122 // longjmp() and throw() must not violate the entry/exit criteria.
7123 CS->getCapturedDecl()->setNothrow();
7124 for (int ThisCaptureLevel =
7125 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7126 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7127 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7128 // 1.2.2 OpenMP Language Terminology
7129 // Structured block - An executable statement with a single entry at the
7130 // top and a single exit at the bottom.
7131 // The point of exit cannot be a branch out of the structured block.
7132 // longjmp() and throw() must not violate the entry/exit criteria.
7133 CS->getCapturedDecl()->setNothrow();
7134 }
7135
7136
7137 OMPLoopDirective::HelperExprs B;
7138 // In presence of clause 'collapse' with number of loops, it will
7139 // define the nested loops number.
7140 unsigned NestedLoopCount = CheckOpenMPLoop(
7141 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7142 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7143 VarsWithImplicitDSA, B);
7144
7145 if (NestedLoopCount == 0)
7146 return StmtError();
7147
7148 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7149, __extension__ __PRETTY_FUNCTION__))
7149 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7149, __extension__ __PRETTY_FUNCTION__))
;
7150
7151 if (!CurContext->isDependentContext()) {
7152 // Finalize the clauses that need pre-built expressions for CodeGen.
7153 for (auto C : Clauses) {
7154 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7155 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7156 B.NumIterations, *this, CurScope,
7157 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7158 return StmtError();
7159 }
7160 }
7161
7162 if (checkSimdlenSafelenSpecified(*this, Clauses))
7163 return StmtError();
7164
7165 getCurFunction()->setHasBranchProtectedScope();
7166
7167 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7168
7169 return OMPTeamsDistributeSimdDirective::Create(
7170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7171}
7172
7173StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7175 SourceLocation EndLoc,
7176 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7177 if (!AStmt)
7178 return StmtError();
7179
7180 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7181 // 1.2.2 OpenMP Language Terminology
7182 // Structured block - An executable statement with a single entry at the
7183 // top and a single exit at the bottom.
7184 // The point of exit cannot be a branch out of the structured block.
7185 // longjmp() and throw() must not violate the entry/exit criteria.
7186 CS->getCapturedDecl()->setNothrow();
7187
7188 for (int ThisCaptureLevel =
7189 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7190 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7191 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7192 // 1.2.2 OpenMP Language Terminology
7193 // Structured block - An executable statement with a single entry at the
7194 // top and a single exit at the bottom.
7195 // The point of exit cannot be a branch out of the structured block.
7196 // longjmp() and throw() must not violate the entry/exit criteria.
7197 CS->getCapturedDecl()->setNothrow();
7198 }
7199
7200 OMPLoopDirective::HelperExprs B;
7201 // In presence of clause 'collapse' with number of loops, it will
7202 // define the nested loops number.
7203 auto NestedLoopCount = CheckOpenMPLoop(
7204 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7205 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7206 VarsWithImplicitDSA, B);
7207
7208 if (NestedLoopCount == 0)
7209 return StmtError();
7210
7211 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7212, __extension__ __PRETTY_FUNCTION__))
7212 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7212, __extension__ __PRETTY_FUNCTION__))
;
7213
7214 if (!CurContext->isDependentContext()) {
7215 // Finalize the clauses that need pre-built expressions for CodeGen.
7216 for (auto C : Clauses) {
7217 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7218 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7219 B.NumIterations, *this, CurScope,
7220 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
7221 return StmtError();
7222 }
7223 }
7224
7225 if (checkSimdlenSafelenSpecified(*this, Clauses))
7226 return StmtError();
7227
7228 getCurFunction()->setHasBranchProtectedScope();
7229
7230 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7231
7232 return OMPTeamsDistributeParallelForSimdDirective::Create(
7233 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7234}
7235
7236StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7237 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7238 SourceLocation EndLoc,
7239 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7240 if (!AStmt)
7241 return StmtError();
7242
7243 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7244 // 1.2.2 OpenMP Language Terminology
7245 // Structured block - An executable statement with a single entry at the
7246 // top and a single exit at the bottom.
7247 // The point of exit cannot be a branch out of the structured block.
7248 // longjmp() and throw() must not violate the entry/exit criteria.
7249 CS->getCapturedDecl()->setNothrow();
7250
7251 for (int ThisCaptureLevel =
7252 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7253 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7254 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7255 // 1.2.2 OpenMP Language Terminology
7256 // Structured block - An executable statement with a single entry at the
7257 // top and a single exit at the bottom.
7258 // The point of exit cannot be a branch out of the structured block.
7259 // longjmp() and throw() must not violate the entry/exit criteria.
7260 CS->getCapturedDecl()->setNothrow();
7261 }
7262
7263 OMPLoopDirective::HelperExprs B;
7264 // In presence of clause 'collapse' with number of loops, it will
7265 // define the nested loops number.
7266 unsigned NestedLoopCount = CheckOpenMPLoop(
7267 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7268 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7269 VarsWithImplicitDSA, B);
7270
7271 if (NestedLoopCount == 0)
7272 return StmtError();
7273
7274 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7275, __extension__ __PRETTY_FUNCTION__))
7275 "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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7275, __extension__ __PRETTY_FUNCTION__))
;
7276
7277 getCurFunction()->setHasBranchProtectedScope();
7278
7279 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentTeamsRegionLoc(StartLoc);
7280
7281 return OMPTeamsDistributeParallelForDirective::Create(
7282 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7283 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
7284}
7285
7286StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7287 Stmt *AStmt,
7288 SourceLocation StartLoc,
7289 SourceLocation EndLoc) {
7290 if (!AStmt)
7291 return StmtError();
7292
7293 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7294 // 1.2.2 OpenMP Language Terminology
7295 // Structured block - An executable statement with a single entry at the
7296 // top and a single exit at the bottom.
7297 // The point of exit cannot be a branch out of the structured block.
7298 // longjmp() and throw() must not violate the entry/exit criteria.
7299 CS->getCapturedDecl()->setNothrow();
7300
7301 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7302 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7303 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7304 // 1.2.2 OpenMP Language Terminology
7305 // Structured block - An executable statement with a single entry at the
7306 // top and a single exit at the bottom.
7307 // The point of exit cannot be a branch out of the structured block.
7308 // longjmp() and throw() must not violate the entry/exit criteria.
7309 CS->getCapturedDecl()->setNothrow();
7310 }
7311 getCurFunction()->setHasBranchProtectedScope();
7312
7313 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7314 AStmt);
7315}
7316
7317StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7318 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7319 SourceLocation EndLoc,
7320 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7321 if (!AStmt)
7322 return StmtError();
7323
7324 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7325 // 1.2.2 OpenMP Language Terminology
7326 // Structured block - An executable statement with a single entry at the
7327 // top and a single exit at the bottom.
7328 // The point of exit cannot be a branch out of the structured block.
7329 // longjmp() and throw() must not violate the entry/exit criteria.
7330 CS->getCapturedDecl()->setNothrow();
7331 for (int ThisCaptureLevel =
7332 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7333 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7334 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7335 // 1.2.2 OpenMP Language Terminology
7336 // Structured block - An executable statement with a single entry at the
7337 // top and a single exit at the bottom.
7338 // The point of exit cannot be a branch out of the structured block.
7339 // longjmp() and throw() must not violate the entry/exit criteria.
7340 CS->getCapturedDecl()->setNothrow();
7341 }
7342
7343 OMPLoopDirective::HelperExprs B;
7344 // In presence of clause 'collapse' with number of loops, it will
7345 // define the nested loops number.
7346 auto NestedLoopCount = CheckOpenMPLoop(
7347 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7348 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
7349 VarsWithImplicitDSA, B);
7350 if (NestedLoopCount == 0)
7351 return StmtError();
7352
7353 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-6.0~svn320940/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 7354, __extension__ __PRETTY_FUNCTION__))
7354 "om