Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaOpenMP.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/lib/Sema -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp -faddrsig
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/// 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 const Expr *checkMapClauseExpressionBase(
39 Sema &SemaRef, Expr *E,
40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41 OpenMPClauseKind CKind, bool NoDiagnose);
42
43namespace {
44/// Default data sharing attributes, which can be applied to directive.
45enum DefaultDataSharingAttributes {
46 DSA_unspecified = 0, /// Data sharing attribute not specified.
47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
48 DSA_shared = 1 << 1, /// 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/// Stack for tracking declarations used in OpenMP directives and
58/// clauses and their data-sharing attributes.
59class DSAStackTy {
60public:
61 struct DSAVarData {
62 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
64 const Expr *RefExpr = nullptr;
65 DeclRefExpr *PrivateCopy = nullptr;
66 SourceLocation ImplicitDSALoc;
67 DSAVarData() = default;
68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70 SourceLocation ImplicitDSALoc)
71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73 };
74 using OperatorOffsetTy =
75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
76 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78
79private:
80 struct DSAInfo {
81 OpenMPClauseKind Attributes = OMPC_unknown;
82 /// Pointer to a reference expression and a flag which shows that the
83 /// variable is marked as lastprivate(true) or not (false).
84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85 DeclRefExpr *PrivateCopy = nullptr;
86 };
87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92 /// Struct that associates a component with the clause kind where they are
93 /// found.
94 struct MappedExprComponentTy {
95 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
96 OpenMPClauseKind Kind = OMPC_unknown;
97 };
98 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102 struct ReductionData {
103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104 SourceRange ReductionRange;
105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106 ReductionData() = default;
107 void set(BinaryOperatorKind BO, SourceRange RR) {
108 ReductionRange = RR;
109 ReductionOp = BO;
110 }
111 void set(const Expr *RefExpr, SourceRange RR) {
112 ReductionRange = RR;
113 ReductionOp = RefExpr;
114 }
115 };
116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118
119 struct SharingMapTy {
120 DeclSAMapTy SharingMap;
121 DeclReductionMapTy ReductionMap;
122 AlignedMapTy AlignedMap;
123 MappedExprComponentsTy MappedExprComponents;
124 LoopControlVariablesMapTy LCVMap;
125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
126 SourceLocation DefaultAttrLoc;
127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128 SourceLocation DefaultMapAttrLoc;
129 OpenMPDirectiveKind Directive = OMPD_unknown;
130 DeclarationNameInfo DirectiveName;
131 Scope *CurScope = nullptr;
132 SourceLocation ConstructLoc;
133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134 /// get the data (loop counters etc.) about enclosing loop-based construct.
135 /// This data is required during codegen.
136 DoacrossDependMapTy DoacrossDepends;
137 /// first argument (Expr *) contains optional argument of the
138 /// 'ordered' clause, the second one is true if the regions has 'ordered'
139 /// clause, false otherwise.
140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
141 bool NowaitRegion = false;
142 bool CancelRegion = false;
143 unsigned AssociatedLoops = 1;
144 SourceLocation InnerTeamsRegionLoc;
145 /// Reference to the taskgroup task_reduction reference expression.
146 Expr *TaskgroupReductionRef = nullptr;
147 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
148 Scope *CurScope, SourceLocation Loc)
149 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
150 ConstructLoc(Loc) {}
151 SharingMapTy() = default;
152 };
153
154 using StackTy = SmallVector<SharingMapTy, 4>;
155
156 /// Stack of used declaration and their data-sharing attributes.
157 DeclSAMapTy Threadprivates;
158 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
159 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
160 /// true, if check for DSA must be from parent directive, false, if
161 /// from current directive.
162 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
163 Sema &SemaRef;
164 bool ForceCapturing = false;
165 CriticalsWithHintsTy Criticals;
166
167 using iterator = StackTy::const_reverse_iterator;
168
169 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
170
171 /// Checks if the variable is a local for OpenMP region.
172 bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
173
174 bool isStackEmpty() const {
175 return Stack.empty() ||
176 Stack.back().second != CurrentNonCapturingFunctionScope ||
177 Stack.back().first.empty();
178 }
179
180 /// Vector of previously declared requires directives
181 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
182
183public:
184 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
185
186 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
187 OpenMPClauseKind getClauseParsingMode() const {
188 assert(isClauseParsingMode() && "Must be in clause parsing mode.")((isClauseParsingMode() && "Must be in clause parsing mode."
) ? static_cast<void> (0) : __assert_fail ("isClauseParsingMode() && \"Must be in clause parsing mode.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 188, __PRETTY_FUNCTION__))
;
189 return ClauseKindMode;
190 }
191 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
192
193 bool isForceVarCapturing() const { return ForceCapturing; }
194 void setForceVarCapturing(bool V) { ForceCapturing = V; }
195
196 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
197 Scope *CurScope, SourceLocation Loc) {
198 if (Stack.empty() ||
199 Stack.back().second != CurrentNonCapturingFunctionScope)
200 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
201 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
202 Stack.back().first.back().DefaultAttrLoc = Loc;
203 }
204
205 void pop() {
206 assert(!Stack.back().first.empty() &&((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 207, __PRETTY_FUNCTION__))
207 "Data-sharing attributes stack is empty!")((!Stack.back().first.empty() && "Data-sharing attributes stack is empty!"
) ? static_cast<void> (0) : __assert_fail ("!Stack.back().first.empty() && \"Data-sharing attributes stack is empty!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 207, __PRETTY_FUNCTION__))
;
208 Stack.back().first.pop_back();
209 }
210
211 /// Start new OpenMP region stack in new non-capturing function.
212 void pushFunction() {
213 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
214 assert(!isa<CapturingScopeInfo>(CurFnScope))((!isa<CapturingScopeInfo>(CurFnScope)) ? static_cast<
void> (0) : __assert_fail ("!isa<CapturingScopeInfo>(CurFnScope)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 214, __PRETTY_FUNCTION__))
;
215 CurrentNonCapturingFunctionScope = CurFnScope;
216 }
217 /// Pop region stack for non-capturing function.
218 void popFunction(const FunctionScopeInfo *OldFSI) {
219 if (!Stack.empty() && Stack.back().second == OldFSI) {
220 assert(Stack.back().first.empty())((Stack.back().first.empty()) ? static_cast<void> (0) :
__assert_fail ("Stack.back().first.empty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 220, __PRETTY_FUNCTION__))
;
221 Stack.pop_back();
222 }
223 CurrentNonCapturingFunctionScope = nullptr;
224 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
225 if (!isa<CapturingScopeInfo>(FSI)) {
226 CurrentNonCapturingFunctionScope = FSI;
227 break;
228 }
229 }
230 }
231
232 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
233 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
234 }
235 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
236 getCriticalWithHint(const DeclarationNameInfo &Name) const {
237 auto I = Criticals.find(Name.getAsString());
238 if (I != Criticals.end())
239 return I->second;
240 return std::make_pair(nullptr, llvm::APSInt());
241 }
242 /// If 'aligned' declaration for given variable \a D was not seen yet,
243 /// add it and return NULL; otherwise return previous occurrence's expression
244 /// for diagnostics.
245 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
246
247 /// Register specified variable as loop control variable.
248 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
249 /// Check if the specified variable is a loop control variable for
250 /// current region.
251 /// \return The index of the loop control variable in the list of associated
252 /// for-loops (from outer to inner).
253 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
254 /// Check if the specified variable is a loop control variable for
255 /// parent region.
256 /// \return The index of the loop control variable in the list of associated
257 /// for-loops (from outer to inner).
258 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
259 /// Get the loop control variable for the I-th loop (or nullptr) in
260 /// parent directive.
261 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
262
263 /// Adds explicit data sharing attribute to the specified declaration.
264 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
265 DeclRefExpr *PrivateCopy = nullptr);
266
267 /// Adds additional information for the reduction items with the reduction id
268 /// represented as an operator.
269 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
270 BinaryOperatorKind BOK);
271 /// Adds additional information for the reduction items with the reduction id
272 /// represented as reduction identifier.
273 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
274 const Expr *ReductionRef);
275 /// Returns the location and reduction operation from the innermost parent
276 /// region for the given \p D.
277 const DSAVarData
278 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
279 BinaryOperatorKind &BOK,
280 Expr *&TaskgroupDescriptor) const;
281 /// Returns the location and reduction operation from the innermost parent
282 /// region for the given \p D.
283 const DSAVarData
284 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
285 const Expr *&ReductionRef,
286 Expr *&TaskgroupDescriptor) const;
287 /// Return reduction reference expression for the current taskgroup.
288 Expr *getTaskgroupReductionRef() const {
289 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&((Stack.back().first.back().Directive == OMPD_taskgroup &&
"taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 291, __PRETTY_FUNCTION__))
290 "taskgroup reference expression requested for non taskgroup "((Stack.back().first.back().Directive == OMPD_taskgroup &&
"taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 291, __PRETTY_FUNCTION__))
291 "directive.")((Stack.back().first.back().Directive == OMPD_taskgroup &&
"taskgroup reference expression requested for non taskgroup "
"directive.") ? static_cast<void> (0) : __assert_fail (
"Stack.back().first.back().Directive == OMPD_taskgroup && \"taskgroup reference expression requested for non taskgroup \" \"directive.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 291, __PRETTY_FUNCTION__))
;
292 return Stack.back().first.back().TaskgroupReductionRef;
293 }
294 /// Checks if the given \p VD declaration is actually a taskgroup reduction
295 /// descriptor variable at the \p Level of OpenMP regions.
296 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
297 return Stack.back().first[Level].TaskgroupReductionRef &&
298 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
299 ->getDecl() == VD;
300 }
301
302 /// Returns data sharing attributes from top of the stack for the
303 /// specified declaration.
304 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
305 /// Returns data-sharing attributes for the specified declaration.
306 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
307 /// Checks if the specified variables has data-sharing attributes which
308 /// match specified \a CPred predicate in any directive which matches \a DPred
309 /// predicate.
310 const DSAVarData
311 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
312 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
313 bool FromParent) const;
314 /// Checks if the specified variables has data-sharing attributes which
315 /// match specified \a CPred predicate in any innermost directive which
316 /// matches \a DPred predicate.
317 const DSAVarData
318 hasInnermostDSA(ValueDecl *D,
319 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
320 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
321 bool FromParent) const;
322 /// Checks if the specified variables has explicit data-sharing
323 /// attributes which match specified \a CPred predicate at the specified
324 /// OpenMP region.
325 bool hasExplicitDSA(const ValueDecl *D,
326 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
327 unsigned Level, bool NotLastprivate = false) const;
328
329 /// Returns true if the directive at level \Level matches in the
330 /// specified \a DPred predicate.
331 bool hasExplicitDirective(
332 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
333 unsigned Level) const;
334
335 /// Finds a directive which matches specified \a DPred predicate.
336 bool hasDirective(
337 const llvm::function_ref<bool(
338 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
339 DPred,
340 bool FromParent) const;
341
342 /// Returns currently analyzed directive.
343 OpenMPDirectiveKind getCurrentDirective() const {
344 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
345 }
346 /// Returns directive kind at specified level.
347 OpenMPDirectiveKind getDirective(unsigned Level) const {
348 assert(!isStackEmpty() && "No directive at specified level.")((!isStackEmpty() && "No directive at specified level."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"No directive at specified level.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 348, __PRETTY_FUNCTION__))
;
349 return Stack.back().first[Level].Directive;
350 }
351 /// Returns parent directive.
352 OpenMPDirectiveKind getParentDirective() const {
353 if (isStackEmpty() || Stack.back().first.size() == 1)
354 return OMPD_unknown;
355 return std::next(Stack.back().first.rbegin())->Directive;
356 }
357
358 /// Add requires decl to internal vector
359 void addRequiresDecl(OMPRequiresDecl *RD) {
360 RequiresDecls.push_back(RD);
361 }
362
363 /// Checks for a duplicate clause amongst previously declared requires
364 /// directives
365 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
366 bool IsDuplicate = false;
367 for (OMPClause *CNew : ClauseList) {
368 for (const OMPRequiresDecl *D : RequiresDecls) {
369 for (const OMPClause *CPrev : D->clauselists()) {
370 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
371 SemaRef.Diag(CNew->getBeginLoc(),
372 diag::err_omp_requires_clause_redeclaration)
373 << getOpenMPClauseName(CNew->getClauseKind());
374 SemaRef.Diag(CPrev->getBeginLoc(),
375 diag::note_omp_requires_previous_clause)
376 << getOpenMPClauseName(CPrev->getClauseKind());
377 IsDuplicate = true;
378 }
379 }
380 }
381 }
382 return IsDuplicate;
383 }
384
385 /// Set default data sharing attribute to none.
386 void setDefaultDSANone(SourceLocation Loc) {
387 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 387, __PRETTY_FUNCTION__))
;
388 Stack.back().first.back().DefaultAttr = DSA_none;
389 Stack.back().first.back().DefaultAttrLoc = Loc;
390 }
391 /// Set default data sharing attribute to shared.
392 void setDefaultDSAShared(SourceLocation Loc) {
393 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 393, __PRETTY_FUNCTION__))
;
394 Stack.back().first.back().DefaultAttr = DSA_shared;
395 Stack.back().first.back().DefaultAttrLoc = Loc;
396 }
397 /// Set default data mapping attribute to 'tofrom:scalar'.
398 void setDefaultDMAToFromScalar(SourceLocation Loc) {
399 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 399, __PRETTY_FUNCTION__))
;
400 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
401 Stack.back().first.back().DefaultMapAttrLoc = Loc;
402 }
403
404 DefaultDataSharingAttributes getDefaultDSA() const {
405 return isStackEmpty() ? DSA_unspecified
406 : Stack.back().first.back().DefaultAttr;
407 }
408 SourceLocation getDefaultDSALocation() const {
409 return isStackEmpty() ? SourceLocation()
410 : Stack.back().first.back().DefaultAttrLoc;
411 }
412 DefaultMapAttributes getDefaultDMA() const {
413 return isStackEmpty() ? DMA_unspecified
414 : Stack.back().first.back().DefaultMapAttr;
415 }
416 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
417 return Stack.back().first[Level].DefaultMapAttr;
418 }
419 SourceLocation getDefaultDMALocation() const {
420 return isStackEmpty() ? SourceLocation()
421 : Stack.back().first.back().DefaultMapAttrLoc;
422 }
423
424 /// Checks if the specified variable is a threadprivate.
425 bool isThreadPrivate(VarDecl *D) {
426 const DSAVarData DVar = getTopDSA(D, false);
427 return isOpenMPThreadPrivate(DVar.CKind);
428 }
429
430 /// Marks current region as ordered (it has an 'ordered' clause).
431 void setOrderedRegion(bool IsOrdered, const Expr *Param,
432 OMPOrderedClause *Clause) {
433 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 433, __PRETTY_FUNCTION__))
;
434 if (IsOrdered)
435 Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
436 else
437 Stack.back().first.back().OrderedRegion.reset();
438 }
439 /// Returns true, if region is ordered (has associated 'ordered' clause),
440 /// false - otherwise.
441 bool isOrderedRegion() const {
442 if (isStackEmpty())
443 return false;
444 return Stack.back().first.rbegin()->OrderedRegion.hasValue();
445 }
446 /// Returns optional parameter for the ordered region.
447 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
448 if (isStackEmpty() ||
449 !Stack.back().first.rbegin()->OrderedRegion.hasValue())
450 return std::make_pair(nullptr, nullptr);
451 return Stack.back().first.rbegin()->OrderedRegion.getValue();
452 }
453 /// Returns true, if parent region is ordered (has associated
454 /// 'ordered' clause), false - otherwise.
455 bool isParentOrderedRegion() const {
456 if (isStackEmpty() || Stack.back().first.size() == 1)
457 return false;
458 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
459 }
460 /// Returns optional parameter for the ordered region.
461 std::pair<const Expr *, OMPOrderedClause *>
462 getParentOrderedRegionParam() const {
463 if (isStackEmpty() || Stack.back().first.size() == 1 ||
464 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
465 return std::make_pair(nullptr, nullptr);
466 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
467 }
468 /// Marks current region as nowait (it has a 'nowait' clause).
469 void setNowaitRegion(bool IsNowait = true) {
470 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 470, __PRETTY_FUNCTION__))
;
471 Stack.back().first.back().NowaitRegion = IsNowait;
472 }
473 /// Returns true, if parent region is nowait (has associated
474 /// 'nowait' clause), false - otherwise.
475 bool isParentNowaitRegion() const {
476 if (isStackEmpty() || Stack.back().first.size() == 1)
477 return false;
478 return std::next(Stack.back().first.rbegin())->NowaitRegion;
479 }
480 /// Marks parent region as cancel region.
481 void setParentCancelRegion(bool Cancel = true) {
482 if (!isStackEmpty() && Stack.back().first.size() > 1) {
483 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
484 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
485 }
486 }
487 /// Return true if current region has inner cancel construct.
488 bool isCancelRegion() const {
489 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
490 }
491
492 /// Set collapse value for the region.
493 void setAssociatedLoops(unsigned Val) {
494 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 494, __PRETTY_FUNCTION__))
;
495 Stack.back().first.back().AssociatedLoops = Val;
496 }
497 /// Return collapse value for region.
498 unsigned getAssociatedLoops() const {
499 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
500 }
501
502 /// Marks current target region as one with closely nested teams
503 /// region.
504 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
505 if (!isStackEmpty() && Stack.back().first.size() > 1) {
506 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
507 TeamsRegionLoc;
508 }
509 }
510 /// Returns true, if current region has closely nested teams region.
511 bool hasInnerTeamsRegion() const {
512 return getInnerTeamsRegionLoc().isValid();
513 }
514 /// Returns location of the nested teams region (if any).
515 SourceLocation getInnerTeamsRegionLoc() const {
516 return isStackEmpty() ? SourceLocation()
517 : Stack.back().first.back().InnerTeamsRegionLoc;
518 }
519
520 Scope *getCurScope() const {
521 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
522 }
523 SourceLocation getConstructLoc() const {
524 return isStackEmpty() ? SourceLocation()
525 : Stack.back().first.back().ConstructLoc;
526 }
527
528 /// Do the check specified in \a Check to all component lists and return true
529 /// if any issue is found.
530 bool checkMappableExprComponentListsForDecl(
531 const ValueDecl *VD, bool CurrentRegionOnly,
532 const llvm::function_ref<
533 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
534 OpenMPClauseKind)>
535 Check) const {
536 if (isStackEmpty())
537 return false;
538 auto SI = Stack.back().first.rbegin();
539 auto SE = Stack.back().first.rend();
540
541 if (SI == SE)
542 return false;
543
544 if (CurrentRegionOnly)
545 SE = std::next(SI);
546 else
547 std::advance(SI, 1);
548
549 for (; SI != SE; ++SI) {
550 auto MI = SI->MappedExprComponents.find(VD);
551 if (MI != SI->MappedExprComponents.end())
552 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
553 MI->second.Components)
554 if (Check(L, MI->second.Kind))
555 return true;
556 }
557 return false;
558 }
559
560 /// Do the check specified in \a Check to all component lists at a given level
561 /// and return true if any issue is found.
562 bool checkMappableExprComponentListsForDeclAtLevel(
563 const ValueDecl *VD, unsigned Level,
564 const llvm::function_ref<
565 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
566 OpenMPClauseKind)>
567 Check) const {
568 if (isStackEmpty())
569 return false;
570
571 auto StartI = Stack.back().first.begin();
572 auto EndI = Stack.back().first.end();
573 if (std::distance(StartI, EndI) <= (int)Level)
574 return false;
575 std::advance(StartI, Level);
576
577 auto MI = StartI->MappedExprComponents.find(VD);
578 if (MI != StartI->MappedExprComponents.end())
579 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
580 MI->second.Components)
581 if (Check(L, MI->second.Kind))
582 return true;
583 return false;
584 }
585
586 /// Create a new mappable expression component list associated with a given
587 /// declaration and initialize it with the provided list of components.
588 void addMappableExpressionComponents(
589 const ValueDecl *VD,
590 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
591 OpenMPClauseKind WhereFoundClauseKind) {
592 assert(!isStackEmpty() &&((!isStackEmpty() && "Not expecting to retrieve components from a empty stack!"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 593, __PRETTY_FUNCTION__))
593 "Not expecting to retrieve components from a empty stack!")((!isStackEmpty() && "Not expecting to retrieve components from a empty stack!"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Not expecting to retrieve components from a empty stack!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 593, __PRETTY_FUNCTION__))
;
594 MappedExprComponentTy &MEC =
595 Stack.back().first.back().MappedExprComponents[VD];
596 // Create new entry and append the new components there.
597 MEC.Components.resize(MEC.Components.size() + 1);
598 MEC.Components.back().append(Components.begin(), Components.end());
599 MEC.Kind = WhereFoundClauseKind;
600 }
601
602 unsigned getNestingLevel() const {
603 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 603, __PRETTY_FUNCTION__))
;
604 return Stack.back().first.size() - 1;
605 }
606 void addDoacrossDependClause(OMPDependClause *C,
607 const OperatorOffsetTy &OpsOffs) {
608 assert(!isStackEmpty() && Stack.back().first.size() > 1)((!isStackEmpty() && Stack.back().first.size() > 1
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 608, __PRETTY_FUNCTION__))
;
609 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
610 assert(isOpenMPWorksharingDirective(StackElem.Directive))((isOpenMPWorksharingDirective(StackElem.Directive)) ? static_cast
<void> (0) : __assert_fail ("isOpenMPWorksharingDirective(StackElem.Directive)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 610, __PRETTY_FUNCTION__))
;
611 StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
612 }
613 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
614 getDoacrossDependClauses() const {
615 assert(!isStackEmpty())((!isStackEmpty()) ? static_cast<void> (0) : __assert_fail
("!isStackEmpty()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 615, __PRETTY_FUNCTION__))
;
616 const SharingMapTy &StackElem = Stack.back().first.back();
617 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
618 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
619 return llvm::make_range(Ref.begin(), Ref.end());
620 }
621 return llvm::make_range(StackElem.DoacrossDepends.end(),
622 StackElem.DoacrossDepends.end());
623 }
624};
625bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
626 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
627 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
628}
629
630} // namespace
631
632static const Expr *getExprAsWritten(const Expr *E) {
633 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
634 E = ExprTemp->getSubExpr();
635
636 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
637 E = MTE->GetTemporaryExpr();
638
639 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
640 E = Binder->getSubExpr();
641
642 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
643 E = ICE->getSubExprAsWritten();
644 return E->IgnoreParens();
645}
646
647static Expr *getExprAsWritten(Expr *E) {
648 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
649}
650
651static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
652 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
653 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
654 D = ME->getMemberDecl();
655 const auto *VD = dyn_cast<VarDecl>(D);
656 const auto *FD = dyn_cast<FieldDecl>(D);
657 if (VD != nullptr) {
658 VD = VD->getCanonicalDecl();
659 D = VD;
660 } else {
661 assert(FD)((FD) ? static_cast<void> (0) : __assert_fail ("FD", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 661, __PRETTY_FUNCTION__))
;
662 FD = FD->getCanonicalDecl();
663 D = FD;
664 }
665 return D;
666}
667
668static ValueDecl *getCanonicalDecl(ValueDecl *D) {
669 return const_cast<ValueDecl *>(
670 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
671}
672
673DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
674 ValueDecl *D) const {
675 D = getCanonicalDecl(D);
676 auto *VD = dyn_cast<VarDecl>(D);
677 const auto *FD = dyn_cast<FieldDecl>(D);
678 DSAVarData DVar;
679 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
681 // in a region but not in construct]
682 // File-scope or namespace-scope variables referenced in called routines
683 // in the region are shared unless they appear in a threadprivate
684 // directive.
685 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
686 DVar.CKind = OMPC_shared;
687
688 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
689 // in a region but not in construct]
690 // Variables with static storage duration that are declared in called
691 // routines in the region are shared.
692 if (VD && VD->hasGlobalStorage())
693 DVar.CKind = OMPC_shared;
694
695 // Non-static data members are shared by default.
696 if (FD)
697 DVar.CKind = OMPC_shared;
698
699 return DVar;
700 }
701
702 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
703 // in a Construct, C/C++, predetermined, p.1]
704 // Variables with automatic storage duration that are declared in a scope
705 // inside the construct are private.
706 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
707 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
708 DVar.CKind = OMPC_private;
709 return DVar;
710 }
711
712 DVar.DKind = Iter->Directive;
713 // Explicitly specified attributes and local variables with predetermined
714 // attributes.
715 if (Iter->SharingMap.count(D)) {
716 const DSAInfo &Data = Iter->SharingMap.lookup(D);
717 DVar.RefExpr = Data.RefExpr.getPointer();
718 DVar.PrivateCopy = Data.PrivateCopy;
719 DVar.CKind = Data.Attributes;
720 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
721 return DVar;
722 }
723
724 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
725 // in a Construct, C/C++, implicitly determined, p.1]
726 // In a parallel or task construct, the data-sharing attributes of these
727 // variables are determined by the default clause, if present.
728 switch (Iter->DefaultAttr) {
729 case DSA_shared:
730 DVar.CKind = OMPC_shared;
731 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
732 return DVar;
733 case DSA_none:
734 return DVar;
735 case DSA_unspecified:
736 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
737 // in a Construct, implicitly determined, p.2]
738 // In a parallel construct, if no default clause is present, these
739 // variables are shared.
740 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
741 if (isOpenMPParallelDirective(DVar.DKind) ||
742 isOpenMPTeamsDirective(DVar.DKind)) {
743 DVar.CKind = OMPC_shared;
744 return DVar;
745 }
746
747 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
748 // in a Construct, implicitly determined, p.4]
749 // In a task construct, if no default clause is present, a variable that in
750 // the enclosing context is determined to be shared by all implicit tasks
751 // bound to the current team is shared.
752 if (isOpenMPTaskingDirective(DVar.DKind)) {
753 DSAVarData DVarTemp;
754 iterator I = Iter, E = Stack.back().first.rend();
755 do {
756 ++I;
757 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
758 // Referenced in a Construct, implicitly determined, p.6]
759 // In a task construct, if no default clause is present, a variable
760 // whose data-sharing attribute is not determined by the rules above is
761 // firstprivate.
762 DVarTemp = getDSA(I, D);
763 if (DVarTemp.CKind != OMPC_shared) {
764 DVar.RefExpr = nullptr;
765 DVar.CKind = OMPC_firstprivate;
766 return DVar;
767 }
768 } while (I != E && !isParallelOrTaskRegion(I->Directive));
769 DVar.CKind =
770 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
771 return DVar;
772 }
773 }
774 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
775 // in a Construct, implicitly determined, p.3]
776 // For constructs other than task, if no default clause is present, these
777 // variables inherit their data-sharing attributes from the enclosing
778 // context.
779 return getDSA(++Iter, D);
780}
781
782const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
783 const Expr *NewDE) {
784 assert(!isStackEmpty() && "Data sharing attributes stack is empty")((!isStackEmpty() && "Data sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 784, __PRETTY_FUNCTION__))
;
785 D = getCanonicalDecl(D);
786 SharingMapTy &StackElem = Stack.back().first.back();
787 auto It = StackElem.AlignedMap.find(D);
788 if (It == StackElem.AlignedMap.end()) {
789 assert(NewDE && "Unexpected nullptr expr to be added into aligned map")((NewDE && "Unexpected nullptr expr to be added into aligned map"
) ? static_cast<void> (0) : __assert_fail ("NewDE && \"Unexpected nullptr expr to be added into aligned map\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 789, __PRETTY_FUNCTION__))
;
790 StackElem.AlignedMap[D] = NewDE;
791 return nullptr;
792 }
793 assert(It->second && "Unexpected nullptr expr in the aligned map")((It->second && "Unexpected nullptr expr in the aligned map"
) ? static_cast<void> (0) : __assert_fail ("It->second && \"Unexpected nullptr expr in the aligned map\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 793, __PRETTY_FUNCTION__))
;
794 return It->second;
795}
796
797void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
798 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 798, __PRETTY_FUNCTION__))
;
799 D = getCanonicalDecl(D);
800 SharingMapTy &StackElem = Stack.back().first.back();
801 StackElem.LCVMap.try_emplace(
802 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
803}
804
805const DSAStackTy::LCDeclInfo
806DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
807 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 807, __PRETTY_FUNCTION__))
;
808 D = getCanonicalDecl(D);
809 const SharingMapTy &StackElem = Stack.back().first.back();
810 auto It = StackElem.LCVMap.find(D);
811 if (It != StackElem.LCVMap.end())
812 return It->second;
813 return {0, nullptr};
814}
815
816const DSAStackTy::LCDeclInfo
817DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
818 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&((!isStackEmpty() && Stack.back().first.size() > 1
&& "Data-sharing attributes stack is empty") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 819, __PRETTY_FUNCTION__))
819 "Data-sharing attributes stack is empty")((!isStackEmpty() && Stack.back().first.size() > 1
&& "Data-sharing attributes stack is empty") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 819, __PRETTY_FUNCTION__))
;
820 D = getCanonicalDecl(D);
821 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
822 auto It = StackElem.LCVMap.find(D);
823 if (It != StackElem.LCVMap.end())
824 return It->second;
825 return {0, nullptr};
826}
827
828const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
829 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&((!isStackEmpty() && Stack.back().first.size() > 1
&& "Data-sharing attributes stack is empty") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 830, __PRETTY_FUNCTION__))
830 "Data-sharing attributes stack is empty")((!isStackEmpty() && Stack.back().first.size() > 1
&& "Data-sharing attributes stack is empty") ? static_cast
<void> (0) : __assert_fail ("!isStackEmpty() && Stack.back().first.size() > 1 && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 830, __PRETTY_FUNCTION__))
;
831 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
832 if (StackElem.LCVMap.size() < I)
833 return nullptr;
834 for (const auto &Pair : StackElem.LCVMap)
835 if (Pair.second.first == I)
836 return Pair.first;
837 return nullptr;
838}
839
840void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
841 DeclRefExpr *PrivateCopy) {
842 D = getCanonicalDecl(D);
843 if (A == OMPC_threadprivate) {
844 DSAInfo &Data = Threadprivates[D];
845 Data.Attributes = A;
846 Data.RefExpr.setPointer(E);
847 Data.PrivateCopy = nullptr;
848 } else {
849 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 849, __PRETTY_FUNCTION__))
;
850 DSAInfo &Data = Stack.back().first.back().SharingMap[D];
851 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 854, __PRETTY_FUNCTION__))
852 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 854, __PRETTY_FUNCTION__))
853 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 854, __PRETTY_FUNCTION__))
854 (isLoopControlVariable(D).first && A == OMPC_private))((Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
(A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate
) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate
) || (isLoopControlVariable(D).first && A == OMPC_private
)) ? static_cast<void> (0) : __assert_fail ("Data.Attributes == OMPC_unknown || (A == Data.Attributes) || (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || (isLoopControlVariable(D).first && A == OMPC_private)"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 854, __PRETTY_FUNCTION__))
;
855 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
856 Data.RefExpr.setInt(/*IntVal=*/true);
857 return;
858 }
859 const bool IsLastprivate =
860 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
861 Data.Attributes = A;
862 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
863 Data.PrivateCopy = PrivateCopy;
864 if (PrivateCopy) {
865 DSAInfo &Data =
866 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
867 Data.Attributes = A;
868 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
869 Data.PrivateCopy = nullptr;
870 }
871 }
872}
873
874/// Build a variable declaration for OpenMP loop iteration variable.
875static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
876 StringRef Name, const AttrVec *Attrs = nullptr,
877 DeclRefExpr *OrigRef = nullptr) {
878 DeclContext *DC = SemaRef.CurContext;
879 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
880 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
881 auto *Decl =
882 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
883 if (Attrs) {
884 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
885 I != E; ++I)
886 Decl->addAttr(*I);
887 }
888 Decl->setImplicit();
889 if (OrigRef) {
890 Decl->addAttr(
891 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
892 }
893 return Decl;
894}
895
896static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
897 SourceLocation Loc,
898 bool RefersToCapture = false) {
899 D->setReferenced();
900 D->markUsed(S.Context);
901 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
902 SourceLocation(), D, RefersToCapture, Loc, Ty,
903 VK_LValue);
904}
905
906void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
907 BinaryOperatorKind BOK) {
908 D = getCanonicalDecl(D);
909 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 909, __PRETTY_FUNCTION__))
;
910 assert(((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 912, __PRETTY_FUNCTION__))
911 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 912, __PRETTY_FUNCTION__))
912 "Additional reduction info may be specified only for reduction items.")((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 912, __PRETTY_FUNCTION__))
;
913 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
914 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 917, __PRETTY_FUNCTION__))
915 Stack.back().first.back().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 917, __PRETTY_FUNCTION__))
916 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 917, __PRETTY_FUNCTION__))
917 "items.")((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 917, __PRETTY_FUNCTION__))
;
918 ReductionData.set(BOK, SR);
919 Expr *&TaskgroupReductionRef =
920 Stack.back().first.back().TaskgroupReductionRef;
921 if (!TaskgroupReductionRef) {
922 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
923 SemaRef.Context.VoidPtrTy, ".task_red.");
924 TaskgroupReductionRef =
925 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
926 }
927}
928
929void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
930 const Expr *ReductionRef) {
931 D = getCanonicalDecl(D);
932 assert(!isStackEmpty() && "Data-sharing attributes stack is empty")((!isStackEmpty() && "Data-sharing attributes stack is empty"
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 932, __PRETTY_FUNCTION__))
;
933 assert(((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 935, __PRETTY_FUNCTION__))
934 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 935, __PRETTY_FUNCTION__))
935 "Additional reduction info may be specified only for reduction items.")((Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction
&& "Additional reduction info may be specified only for reduction items."
) ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 935, __PRETTY_FUNCTION__))
;
936 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
937 assert(ReductionData.ReductionRange.isInvalid() &&((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 940, __PRETTY_FUNCTION__))
938 Stack.back().first.back().Directive == OMPD_taskgroup &&((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 940, __PRETTY_FUNCTION__))
939 "Additional reduction info may be specified only once for reduction "((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 940, __PRETTY_FUNCTION__))
940 "items.")((ReductionData.ReductionRange.isInvalid() && Stack.back
().first.back().Directive == OMPD_taskgroup && "Additional reduction info may be specified only once for reduction "
"items.") ? static_cast<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-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 940, __PRETTY_FUNCTION__))
;
941 ReductionData.set(ReductionRef, SR);
942 Expr *&TaskgroupReductionRef =
943 Stack.back().first.back().TaskgroupReductionRef;
944 if (!TaskgroupReductionRef) {
945 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
946 SemaRef.Context.VoidPtrTy, ".task_red.");
947 TaskgroupReductionRef =
948 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
949 }
950}
951
952const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
953 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
954 Expr *&TaskgroupDescriptor) const {
955 D = getCanonicalDecl(D);
956 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 956, __PRETTY_FUNCTION__))
;
957 if (Stack.back().first.empty())
958 return DSAVarData();
959 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
960 E = Stack.back().first.rend();
961 I != E; std::advance(I, 1)) {
962 const DSAInfo &Data = I->SharingMap.lookup(D);
963 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
964 continue;
965 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
966 if (!ReductionData.ReductionOp ||
967 ReductionData.ReductionOp.is<const Expr *>())
968 return DSAVarData();
969 SR = ReductionData.ReductionRange;
970 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
971 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 973, __PRETTY_FUNCTION__))
972 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 973, __PRETTY_FUNCTION__))
973 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 973, __PRETTY_FUNCTION__))
;
974 TaskgroupDescriptor = I->TaskgroupReductionRef;
975 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
976 Data.PrivateCopy, I->DefaultAttrLoc);
977 }
978 return DSAVarData();
979}
980
981const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
982 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
983 Expr *&TaskgroupDescriptor) const {
984 D = getCanonicalDecl(D);
985 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.")((!isStackEmpty() && "Data-sharing attributes stack is empty."
) ? static_cast<void> (0) : __assert_fail ("!isStackEmpty() && \"Data-sharing attributes stack is empty.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 985, __PRETTY_FUNCTION__))
;
986 if (Stack.back().first.empty())
987 return DSAVarData();
988 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
989 E = Stack.back().first.rend();
990 I != E; std::advance(I, 1)) {
991 const DSAInfo &Data = I->SharingMap.lookup(D);
992 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
993 continue;
994 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
995 if (!ReductionData.ReductionOp ||
996 !ReductionData.ReductionOp.is<const Expr *>())
997 return DSAVarData();
998 SR = ReductionData.ReductionRange;
999 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1000 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1002, __PRETTY_FUNCTION__))
1001 "expression for the descriptor is not "((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1002, __PRETTY_FUNCTION__))
1002 "set.")((I->TaskgroupReductionRef && "taskgroup reduction reference "
"expression for the descriptor is not " "set.") ? static_cast
<void> (0) : __assert_fail ("I->TaskgroupReductionRef && \"taskgroup reduction reference \" \"expression for the descriptor is not \" \"set.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1002, __PRETTY_FUNCTION__))
;
1003 TaskgroupDescriptor = I->TaskgroupReductionRef;
1004 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1005 Data.PrivateCopy, I->DefaultAttrLoc);
1006 }
1007 return DSAVarData();
1008}
1009
1010bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
1011 D = D->getCanonicalDecl();
1012 if (!isStackEmpty()) {
1013 iterator I = Iter, E = Stack.back().first.rend();
1014 Scope *TopScope = nullptr;
1015 while (I != E && !isParallelOrTaskRegion(I->Directive) &&
1016 !isOpenMPTargetExecutionDirective(I->Directive))
1017 ++I;
1018 if (I == E)
1019 return false;
1020 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1021 Scope *CurScope = getCurScope();
1022 while (CurScope != TopScope && !CurScope->isDeclScope(D))
1023 CurScope = CurScope->getParent();
1024 return CurScope != TopScope;
1025 }
1026 return false;
1027}
1028
1029const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1030 bool FromParent) {
1031 D = getCanonicalDecl(D);
1032 DSAVarData DVar;
1033
1034 auto *VD = dyn_cast<VarDecl>(D);
1035 auto TI = Threadprivates.find(D);
1036 if (TI != Threadprivates.end()) {
1037 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1038 DVar.CKind = OMPC_threadprivate;
1039 return DVar;
1040 }
1041 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1042 DVar.RefExpr = buildDeclRefExpr(
1043 SemaRef, VD, D->getType().getNonReferenceType(),
1044 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1045 DVar.CKind = OMPC_threadprivate;
1046 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1047 return DVar;
1048 }
1049 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1050 // in a Construct, C/C++, predetermined, p.1]
1051 // Variables appearing in threadprivate directives are threadprivate.
1052 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1053 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1054 SemaRef.getLangOpts().OpenMPUseTLS &&
1055 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1056 (VD && VD->getStorageClass() == SC_Register &&
1057 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1058 DVar.RefExpr = buildDeclRefExpr(
1059 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1060 DVar.CKind = OMPC_threadprivate;
1061 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1062 return DVar;
1063 }
1064 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1065 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1066 !isLoopControlVariable(D).first) {
1067 iterator IterTarget =
1068 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1069 [](const SharingMapTy &Data) {
1070 return isOpenMPTargetExecutionDirective(Data.Directive);
1071 });
1072 if (IterTarget != Stack.back().first.rend()) {
1073 iterator ParentIterTarget = std::next(IterTarget, 1);
1074 for (iterator Iter = Stack.back().first.rbegin();
1075 Iter != ParentIterTarget; std::advance(Iter, 1)) {
1076 if (isOpenMPLocal(VD, Iter)) {
1077 DVar.RefExpr =
1078 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1079 D->getLocation());
1080 DVar.CKind = OMPC_threadprivate;
1081 return DVar;
1082 }
1083 }
1084 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1085 auto DSAIter = IterTarget->SharingMap.find(D);
1086 if (DSAIter != IterTarget->SharingMap.end() &&
1087 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1088 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1089 DVar.CKind = OMPC_threadprivate;
1090 return DVar;
1091 }
1092 iterator End = Stack.back().first.rend();
1093 if (!SemaRef.isOpenMPCapturedByRef(
1094 D, std::distance(ParentIterTarget, End))) {
1095 DVar.RefExpr =
1096 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1097 IterTarget->ConstructLoc);
1098 DVar.CKind = OMPC_threadprivate;
1099 return DVar;
1100 }
1101 }
1102 }
1103 }
1104
1105 if (isStackEmpty())
1106 // Not in OpenMP execution region and top scope was already checked.
1107 return DVar;
1108
1109 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1110 // in a Construct, C/C++, predetermined, p.4]
1111 // Static data members are shared.
1112 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1113 // in a Construct, C/C++, predetermined, p.7]
1114 // Variables with static storage duration that are declared in a scope
1115 // inside the construct are shared.
1116 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1117 if (VD && VD->isStaticDataMember()) {
1118 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1119 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1120 return DVar;
1121
1122 DVar.CKind = OMPC_shared;
1123 return DVar;
1124 }
1125
1126 QualType Type = D->getType().getNonReferenceType().getCanonicalType();
1127 bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1128 Type = SemaRef.getASTContext().getBaseElementType(Type);
1129 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1130 // in a Construct, C/C++, predetermined, p.6]
1131 // Variables with const qualified type having no mutable member are
1132 // shared.
1133 const CXXRecordDecl *RD =
1134 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1135 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1136 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1137 RD = CTD->getTemplatedDecl();
1138 if (IsConstant &&
1139 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1140 RD->hasMutableFields())) {
1141 // Variables with const-qualified type having no mutable member may be
1142 // listed in a firstprivate clause, even if they are static data members.
1143 DSAVarData DVarTemp =
1144 hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; },
1145 MatchesAlways, FromParent);
1146 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1147 return DVarTemp;
1148
1149 DVar.CKind = OMPC_shared;
1150 return DVar;
1151 }
1152
1153 // Explicitly specified attributes and local variables with predetermined
1154 // attributes.
1155 iterator I = Stack.back().first.rbegin();
1156 iterator EndI = Stack.back().first.rend();
1157 if (FromParent && I != EndI)
1158 std::advance(I, 1);
1159 auto It = I->SharingMap.find(D);
1160 if (It != I->SharingMap.end()) {
1161 const DSAInfo &Data = It->getSecond();
1162 DVar.RefExpr = Data.RefExpr.getPointer();
1163 DVar.PrivateCopy = Data.PrivateCopy;
1164 DVar.CKind = Data.Attributes;
1165 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1166 DVar.DKind = I->Directive;
1167 }
1168
1169 return DVar;
1170}
1171
1172const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1173 bool FromParent) const {
1174 if (isStackEmpty()) {
1175 iterator I;
1176 return getDSA(I, D);
1177 }
1178 D = getCanonicalDecl(D);
1179 iterator StartI = Stack.back().first.rbegin();
1180 iterator EndI = Stack.back().first.rend();
1181 if (FromParent && StartI != EndI)
1182 std::advance(StartI, 1);
1183 return getDSA(StartI, D);
1184}
1185
1186const DSAStackTy::DSAVarData
1187DSAStackTy::hasDSA(ValueDecl *D,
1188 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1189 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1190 bool FromParent) const {
1191 if (isStackEmpty())
1192 return {};
1193 D = getCanonicalDecl(D);
1194 iterator I = Stack.back().first.rbegin();
1195 iterator EndI = Stack.back().first.rend();
1196 if (FromParent && I != EndI)
1197 std::advance(I, 1);
1198 for (; I != EndI; std::advance(I, 1)) {
1199 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1200 continue;
1201 iterator NewI = I;
1202 DSAVarData DVar = getDSA(NewI, D);
1203 if (I == NewI && CPred(DVar.CKind))
1204 return DVar;
1205 }
1206 return {};
1207}
1208
1209const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1210 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1211 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1212 bool FromParent) const {
1213 if (isStackEmpty())
1214 return {};
1215 D = getCanonicalDecl(D);
1216 iterator StartI = Stack.back().first.rbegin();
1217 iterator EndI = Stack.back().first.rend();
1218 if (FromParent && StartI != EndI)
1219 std::advance(StartI, 1);
1220 if (StartI == EndI || !DPred(StartI->Directive))
1221 return {};
1222 iterator NewI = StartI;
1223 DSAVarData DVar = getDSA(NewI, D);
1224 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1225}
1226
1227bool DSAStackTy::hasExplicitDSA(
1228 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1229 unsigned Level, bool NotLastprivate) const {
1230 if (isStackEmpty())
1231 return false;
1232 D = getCanonicalDecl(D);
1233 auto StartI = Stack.back().first.begin();
1234 auto EndI = Stack.back().first.end();
1235 if (std::distance(StartI, EndI) <= (int)Level)
1236 return false;
1237 std::advance(StartI, Level);
1238 auto I = StartI->SharingMap.find(D);
1239 return (I != StartI->SharingMap.end()) &&
1240 I->getSecond().RefExpr.getPointer() &&
1241 CPred(I->getSecond().Attributes) &&
1242 (!NotLastprivate || !I->getSecond().RefExpr.getInt());
1243}
1244
1245bool DSAStackTy::hasExplicitDirective(
1246 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1247 unsigned Level) const {
1248 if (isStackEmpty())
1249 return false;
1250 auto StartI = Stack.back().first.begin();
1251 auto EndI = Stack.back().first.end();
1252 if (std::distance(StartI, EndI) <= (int)Level)
1253 return false;
1254 std::advance(StartI, Level);
1255 return DPred(StartI->Directive);
1256}
1257
1258bool DSAStackTy::hasDirective(
1259 const llvm::function_ref<bool(OpenMPDirectiveKind,
1260 const DeclarationNameInfo &, SourceLocation)>
1261 DPred,
1262 bool FromParent) const {
1263 // We look only in the enclosing region.
1264 if (isStackEmpty())
1265 return false;
1266 auto StartI = std::next(Stack.back().first.rbegin());
1267 auto EndI = Stack.back().first.rend();
1268 if (FromParent && StartI != EndI)
1269 StartI = std::next(StartI);
1270 for (auto I = StartI, EE = EndI; I != EE; ++I) {
1271 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1272 return true;
1273 }
1274 return false;
1275}
1276
1277void Sema::InitDataSharingAttributesStack() {
1278 VarDataSharingAttributesStack = new DSAStackTy(*this);
1279}
1280
1281#define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1282
1283void Sema::pushOpenMPFunctionRegion() {
1284 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pushFunction();
1285}
1286
1287void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1288 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->popFunction(OldFSI);
1289}
1290
1291bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
1292 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1292, __PRETTY_FUNCTION__))
;
1293
1294 ASTContext &Ctx = getASTContext();
1295 bool IsByRef = true;
1296
1297 // Find the directive that is associated with the provided scope.
1298 D = cast<ValueDecl>(D->getCanonicalDecl());
1299 QualType Ty = D->getType();
1300
1301 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1302 // This table summarizes how a given variable should be passed to the device
1303 // given its type and the clauses where it appears. This table is based on
1304 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1305 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1306 //
1307 // =========================================================================
1308 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1309 // | |(tofrom:scalar)| | pvt | | | |
1310 // =========================================================================
1311 // | scl | | | | - | | bycopy|
1312 // | scl | | - | x | - | - | bycopy|
1313 // | scl | | x | - | - | - | null |
1314 // | scl | x | | | - | | byref |
1315 // | scl | x | - | x | - | - | bycopy|
1316 // | scl | x | x | - | - | - | null |
1317 // | scl | | - | - | - | x | byref |
1318 // | scl | x | - | - | - | x | byref |
1319 //
1320 // | agg | n.a. | | | - | | byref |
1321 // | agg | n.a. | - | x | - | - | byref |
1322 // | agg | n.a. | x | - | - | - | null |
1323 // | agg | n.a. | - | - | - | x | byref |
1324 // | agg | n.a. | - | - | - | x[] | byref |
1325 //
1326 // | ptr | n.a. | | | - | | bycopy|
1327 // | ptr | n.a. | - | x | - | - | bycopy|
1328 // | ptr | n.a. | x | - | - | - | null |
1329 // | ptr | n.a. | - | - | - | x | byref |
1330 // | ptr | n.a. | - | - | - | x[] | bycopy|
1331 // | ptr | n.a. | - | - | x | | bycopy|
1332 // | ptr | n.a. | - | - | x | x | bycopy|
1333 // | ptr | n.a. | - | - | x | x[] | bycopy|
1334 // =========================================================================
1335 // Legend:
1336 // scl - scalar
1337 // ptr - pointer
1338 // agg - aggregate
1339 // x - applies
1340 // - - invalid in this combination
1341 // [] - mapped with an array section
1342 // byref - should be mapped by reference
1343 // byval - should be mapped by value
1344 // null - initialize a local variable to null on the device
1345 //
1346 // Observations:
1347 // - All scalar declarations that show up in a map clause have to be passed
1348 // by reference, because they may have been mapped in the enclosing data
1349 // environment.
1350 // - If the scalar value does not fit the size of uintptr, it has to be
1351 // passed by reference, regardless the result in the table above.
1352 // - For pointers mapped by value that have either an implicit map or an
1353 // array section, the runtime library may pass the NULL value to the
1354 // device instead of the value passed to it by the compiler.
1355
1356 if (Ty->isReferenceType())
1357 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1358
1359 // Locate map clauses and see if the variable being captured is referred to
1360 // in any of those clauses. Here we only care about variables, not fields,
1361 // because fields are part of aggregates.
1362 bool IsVariableUsedInMapClause = false;
1363 bool IsVariableAssociatedWithSection = false;
1364
1365 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1366 D, Level,
1367 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1368 OMPClauseMappableExprCommon::MappableExprComponentListRef
1369 MapExprComponents,
1370 OpenMPClauseKind WhereFoundClauseKind) {
1371 // Only the map clause information influences how a variable is
1372 // captured. E.g. is_device_ptr does not require changing the default
1373 // behavior.
1374 if (WhereFoundClauseKind != OMPC_map)
1375 return false;
1376
1377 auto EI = MapExprComponents.rbegin();
1378 auto EE = MapExprComponents.rend();
1379
1380 assert(EI != EE && "Invalid map expression!")((EI != EE && "Invalid map expression!") ? static_cast
<void> (0) : __assert_fail ("EI != EE && \"Invalid map expression!\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1380, __PRETTY_FUNCTION__))
;
1381
1382 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1383 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1384
1385 ++EI;
1386 if (EI == EE)
1387 return false;
1388
1389 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1390 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1391 isa<MemberExpr>(EI->getAssociatedExpression())) {
1392 IsVariableAssociatedWithSection = true;
1393 // There is nothing more we need to know about this variable.
1394 return true;
1395 }
1396
1397 // Keep looking for more map info.
1398 return false;
1399 });
1400
1401 if (IsVariableUsedInMapClause) {
1402 // If variable is identified in a map clause it is always captured by
1403 // reference except if it is a pointer that is dereferenced somehow.
1404 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1405 } else {
1406 // By default, all the data that has a scalar type is mapped by copy
1407 // (except for reduction variables).
1408 IsByRef =
1409 !Ty->isScalarType() ||
1410 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1411 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1412 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1413 }
1414 }
1415
1416 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1417 IsByRef =
1418 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1419 D,
1420 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1421 Level, /*NotLastprivate=*/true) &&
1422 // If the variable is artificial and must be captured by value - try to
1423 // capture by value.
1424 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1425 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1426 }
1427
1428 // When passing data by copy, we need to make sure it fits the uintptr size
1429 // and alignment, because the runtime library only deals with uintptr types.
1430 // If it does not fit the uintptr size, we need to pass the data by reference
1431 // instead.
1432 if (!IsByRef &&
1433 (Ctx.getTypeSizeInChars(Ty) >
1434 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1435 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1436 IsByRef = true;
1437 }
1438
1439 return IsByRef;
1440}
1441
1442unsigned Sema::getOpenMPNestingLevel() const {
1443 assert(getLangOpts().OpenMP)((getLangOpts().OpenMP) ? static_cast<void> (0) : __assert_fail
("getLangOpts().OpenMP", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1443, __PRETTY_FUNCTION__))
;
1444 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel();
1445}
1446
1447bool Sema::isInOpenMPTargetExecutionDirective() const {
1448 return (isOpenMPTargetExecutionDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
1449 !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode()) ||
1450 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDirective(
1451 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1452 SourceLocation) -> bool {
1453 return isOpenMPTargetExecutionDirective(K);
1454 },
1455 false);
1456}
1457
1458VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) {
1459 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1459, __PRETTY_FUNCTION__))
;
1460 D = getCanonicalDecl(D);
1461
1462 // If we are attempting to capture a global variable in a directive with
1463 // 'target' we return true so that this global is also mapped to the device.
1464 //
1465 auto *VD = dyn_cast<VarDecl>(D);
1466 if (VD && !VD->hasLocalStorage()) {
1467 if (isInOpenMPDeclareTargetContext() &&
1468 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1469 // Try to mark variable as declare target if it is used in capturing
1470 // regions.
1471 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1472 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
1473 return nullptr;
1474 } else if (isInOpenMPTargetExecutionDirective()) {
1475 // If the declaration is enclosed in a 'declare target' directive,
1476 // then it should not be captured.
1477 //
1478 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1479 return nullptr;
1480 return VD;
1481 }
1482 }
1483
1484 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective() != OMPD_unknown &&
1485 (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() ||
1486 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getParentDirective() != OMPD_unknown)) {
1487 auto &&Info = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isLoopControlVariable(D);
1488 if (Info.first ||
1489 (VD && VD->hasLocalStorage() &&
1490 isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) ||
1491 (VD && DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isForceVarCapturing()))
1492 return VD ? VD : Info.second;
1493 DSAStackTy::DSAVarData DVarPrivate =
1494 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(D, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
1495 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1496 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1497 DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDSA(D, isOpenMPPrivate,
1498 [](OpenMPDirectiveKind) { return true; },
1499 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode());
1500 if (DVarPrivate.CKind != OMPC_unknown)
1501 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1502 }
1503 return nullptr;
1504}
1505
1506void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1507 unsigned Level) const {
1508 SmallVector<OpenMPDirectiveKind, 4> Regions;
1509 getOpenMPCaptureRegions(Regions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDirective(Level));
1510 FunctionScopesIndex -= Regions.size();
1511}
1512
1513bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1514 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1514, __PRETTY_FUNCTION__))
;
1515 return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(
1516 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1517 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isClauseParsingMode() &&
1518 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getClauseParsingMode() == OMPC_private) ||
1519 // Consider taskgroup reduction descriptor variable a private to avoid
1520 // possible capture in the region.
1521 (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(
1522 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1523 Level) &&
1524 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isTaskgroupReductionRef(D, Level));
1525}
1526
1527void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
1528 unsigned Level) {
1529 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1529, __PRETTY_FUNCTION__))
;
1530 D = getCanonicalDecl(D);
1531 OpenMPClauseKind OMPC = OMPC_unknown;
1532 for (unsigned I = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getNestingLevel() + 1; I > Level; --I) {
1533 const unsigned NewLevel = I - 1;
1534 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDSA(D,
1535 [&OMPC](const OpenMPClauseKind K) {
1536 if (isOpenMPPrivate(K)) {
1537 OMPC = K;
1538 return true;
1539 }
1540 return false;
1541 },
1542 NewLevel))
1543 break;
1544 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->checkMappableExprComponentListsForDeclAtLevel(
1545 D, NewLevel,
1546 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1547 OpenMPClauseKind) { return true; })) {
1548 OMPC = OMPC_map;
1549 break;
1550 }
1551 if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1552 NewLevel)) {
1553 OMPC = OMPC_map;
1554 if (D->getType()->isScalarType() &&
1555 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getDefaultDMAAtLevel(NewLevel) !=
1556 DefaultMapAttributes::DMA_tofrom_scalar)
1557 OMPC = OMPC_firstprivate;
1558 break;
1559 }
1560 }
1561 if (OMPC != OMPC_unknown)
1562 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1563}
1564
1565bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D,
1566 unsigned Level) const {
1567 assert(LangOpts.OpenMP && "OpenMP is not allowed")((LangOpts.OpenMP && "OpenMP is not allowed") ? static_cast
<void> (0) : __assert_fail ("LangOpts.OpenMP && \"OpenMP is not allowed\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 1567, __PRETTY_FUNCTION__))
;
1568 // Return true if the current level is no longer enclosed in a target region.
1569
1570 const auto *VD = dyn_cast<VarDecl>(D);
1571 return VD && !VD->hasLocalStorage() &&
1572 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1573 Level);
1574}
1575
1576void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
; }
1577
1578void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1579 const DeclarationNameInfo &DirName,
1580 Scope *CurScope, SourceLocation Loc) {
1581 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->push(DKind, DirName, CurScope, Loc);
1582 PushExpressionEvaluationContext(
1583 ExpressionEvaluationContext::PotentiallyEvaluated);
1584}
1585
1586void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1587 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(K);
1588}
1589
1590void Sema::EndOpenMPClause() {
1591 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setClauseParsingMode(/*K=*/OMPC_unknown);
1592}
1593
1594void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1595 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1596 // A variable of class type (or array thereof) that appears in a lastprivate
1597 // clause requires an accessible, unambiguous default constructor for the
1598 // class type, unless the list item is also specified in a firstprivate
1599 // clause.
1600 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1601 for (OMPClause *C : D->clauses()) {
1602 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1603 SmallVector<Expr *, 8> PrivateCopies;
1604 for (Expr *DE : Clause->varlists()) {
1605 if (DE->isValueDependent() || DE->isTypeDependent()) {
1606 PrivateCopies.push_back(nullptr);
1607 continue;
1608 }
1609 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1610 auto *VD = cast<VarDecl>(DRE->getDecl());
1611 QualType Type = VD->getType().getNonReferenceType();
1612 const DSAStackTy::DSAVarData DVar =
1613 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getTopDSA(VD, /*FromParent=*/false);
1614 if (DVar.CKind == OMPC_lastprivate) {
1615 // Generate helper private variable and initialize it with the
1616 // default value. The address of the original variable is replaced
1617 // by the address of the new private variable in CodeGen. This new
1618 // variable is not added to IdResolver, so the code in the OpenMP
1619 // region uses original variable for proper diagnostics.
1620 VarDecl *VDPrivate = buildVarDecl(
1621 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1622 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1623 ActOnUninitializedDecl(VDPrivate);
1624 if (VDPrivate->isInvalidDecl())
1625 continue;
1626 PrivateCopies.push_back(buildDeclRefExpr(
1627 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1628 } else {
1629 // The variable is also a firstprivate, so initialization sequence
1630 // for private copy is generated already.
1631 PrivateCopies.push_back(nullptr);
1632 }
1633 }
1634 // Set initializers to private copies if no errors were found.
1635 if (PrivateCopies.size() == Clause->varlist_size())
1636 Clause->setPrivateCopies(PrivateCopies);
1637 }
1638 }
1639 }
1640
1641 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->pop();
1642 DiscardCleanupsInEvaluationContext();
1643 PopExpressionEvaluationContext();
1644}
1645
1646static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1647 Expr *NumIterations, Sema &SemaRef,
1648 Scope *S, DSAStackTy *Stack);
1649
1650namespace {
1651
1652class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1653private:
1654 Sema &SemaRef;
1655
1656public:
1657 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1658 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1659 NamedDecl *ND = Candidate.getCorrectionDecl();
1660 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1661 return VD->hasGlobalStorage() &&
1662 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1663 SemaRef.getCurScope());
1664 }
1665 return false;
1666 }
1667};
1668
1669class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1670private:
1671 Sema &SemaRef;
1672
1673public:
1674 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1675 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1676 NamedDecl *ND = Candidate.getCorrectionDecl();
1677 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1678 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1679 SemaRef.getCurScope());
1680 }
1681 return false;
1682 }
1683};
1684
1685} // namespace
1686
1687ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1688 CXXScopeSpec &ScopeSpec,
1689 const DeclarationNameInfo &Id) {
1690 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1691 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1692
1693 if (Lookup.isAmbiguous())
1694 return ExprError();
1695
1696 VarDecl *VD;
1697 if (!Lookup.isSingleResult()) {
1698 if (TypoCorrection Corrected = CorrectTypo(
1699 Id, LookupOrdinaryName, CurScope, nullptr,
1700 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1701 diagnoseTypo(Corrected,
1702 PDiag(Lookup.empty()
1703 ? diag::err_undeclared_var_use_suggest
1704 : diag::err_omp_expected_var_arg_suggest)
1705 << Id.getName());
1706 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1707 } else {
1708 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1709 : diag::err_omp_expected_var_arg)
1710 << Id.getName();
1711 return ExprError();
1712 }
1713 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1714 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1715 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1716 return ExprError();
1717 }
1718 Lookup.suppressDiagnostics();
1719
1720 // OpenMP [2.9.2, Syntax, C/C++]
1721 // Variables must be file-scope, namespace-scope, or static block-scope.
1722 if (!VD->hasGlobalStorage()) {
1723 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1724 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1725 bool IsDecl =
1726 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1727 Diag(VD->getLocation(),
1728 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1729 << VD;
1730 return ExprError();
1731 }
1732
1733 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1734 NamedDecl *ND = CanonicalVD;
1735 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1736 // A threadprivate directive for file-scope variables must appear outside
1737 // any definition or declaration.
1738 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1739 !getCurLexicalContext()->isTranslationUnit()) {
1740 Diag(Id.getLoc(), diag::err_omp_var_scope)
1741 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1742 bool IsDecl =
1743 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1744 Diag(VD->getLocation(),
1745 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1746 << VD;
1747 return ExprError();
1748 }
1749 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1750 // A threadprivate directive for static class member variables must appear
1751 // in the class definition, in the same scope in which the member
1752 // variables are declared.
1753 if (CanonicalVD->isStaticDataMember() &&
1754 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1755 Diag(Id.getLoc(), diag::err_omp_var_scope)
1756 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1757 bool IsDecl =
1758 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1759 Diag(VD->getLocation(),
1760 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1761 << VD;
1762 return ExprError();
1763 }
1764 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1765 // A threadprivate directive for namespace-scope variables must appear
1766 // outside any definition or declaration other than the namespace
1767 // definition itself.
1768 if (CanonicalVD->getDeclContext()->isNamespace() &&
1769 (!getCurLexicalContext()->isFileContext() ||
1770 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1771 Diag(Id.getLoc(), diag::err_omp_var_scope)
1772 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1773 bool IsDecl =
1774 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1775 Diag(VD->getLocation(),
1776 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1777 << VD;
1778 return ExprError();
1779 }
1780 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1781 // A threadprivate directive for static block-scope variables must appear
1782 // in the scope of the variable and not in a nested scope.
1783 if (CanonicalVD->isStaticLocal() && CurScope &&
1784 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1785 Diag(Id.getLoc(), diag::err_omp_var_scope)
1786 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1787 bool IsDecl =
1788 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1789 Diag(VD->getLocation(),
1790 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1791 << VD;
1792 return ExprError();
1793 }
1794
1795 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1796 // A threadprivate directive must lexically precede all references to any
1797 // of the variables in its list.
1798 if (VD->isUsed() && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isThreadPrivate(VD)) {
1799 Diag(Id.getLoc(), diag::err_omp_var_used)
1800 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1801 return ExprError();
1802 }
1803
1804 QualType ExprType = VD->getType().getNonReferenceType();
1805 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1806 SourceLocation(), VD,
1807 /*RefersToEnclosingVariableOrCapture=*/false,
1808 Id.getLoc(), ExprType, VK_LValue);
1809}
1810
1811Sema::DeclGroupPtrTy
1812Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1813 ArrayRef<Expr *> VarList) {
1814 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1815 CurContext->addDecl(D);
1816 return DeclGroupPtrTy::make(DeclGroupRef(D));
1817 }
1818 return nullptr;
1819}
1820
1821namespace {
1822class LocalVarRefChecker final
1823 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1824 Sema &SemaRef;
1825
1826public:
1827 bool VisitDeclRefExpr(const DeclRefExpr *E) {
1828 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1829 if (VD->hasLocalStorage()) {
1830 SemaRef.Diag(E->getBeginLoc(),
1831 diag::err_omp_local_var_in_threadprivate_init)
1832 << E->getSourceRange();
1833 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1834 << VD << VD->getSourceRange();
1835 return true;
1836 }
1837 }
1838 return false;
1839 }
1840 bool VisitStmt(const Stmt *S) {
1841 for (const Stmt *Child : S->children()) {
1842 if (Child && Visit(Child))
1843 return true;
1844 }
1845 return false;
1846 }
1847 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1848};
1849} // namespace
1850
1851OMPThreadPrivateDecl *
1852Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1853 SmallVector<Expr *, 8> Vars;
1854 for (Expr *RefExpr : VarList) {
1855 auto *DE = cast<DeclRefExpr>(RefExpr);
1856 auto *VD = cast<VarDecl>(DE->getDecl());
1857 SourceLocation ILoc = DE->getExprLoc();
1858
1859 // Mark variable as used.
1860 VD->setReferenced();
1861 VD->markUsed(Context);
1862
1863 QualType QType = VD->getType();
1864 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1865 // It will be analyzed later.
1866 Vars.push_back(DE);
1867 continue;
1868 }
1869
1870 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1871 // A threadprivate variable must not have an incomplete type.
1872 if (RequireCompleteType(ILoc, VD->getType(),
1873 diag::err_omp_threadprivate_incomplete_type)) {
1874 continue;
1875 }
1876
1877 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1878 // A threadprivate variable must not have a reference type.
1879 if (VD->getType()->isReferenceType()) {
1880 Diag(ILoc, diag::err_omp_ref_type_arg)
1881 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1882 bool IsDecl =
1883 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1884 Diag(VD->getLocation(),
1885 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1886 << VD;
1887 continue;
1888 }
1889
1890 // Check if this is a TLS variable. If TLS is not being supported, produce
1891 // the corresponding diagnostic.
1892 if ((VD->getTLSKind() != VarDecl::TLS_None &&
1893 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1894 getLangOpts().OpenMPUseTLS &&
1895 getASTContext().getTargetInfo().isTLSSupported())) ||
1896 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1897 !VD->isLocalVarDecl())) {
1898 Diag(ILoc, diag::err_omp_var_thread_local)
1899 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1900 bool IsDecl =
1901 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1902 Diag(VD->getLocation(),
1903 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1904 << VD;
1905 continue;
1906 }
1907
1908 // Check if initial value of threadprivate variable reference variable with
1909 // local storage (it is not supported by runtime).
1910 if (const Expr *Init = VD->getAnyInitializer()) {
1911 LocalVarRefChecker Checker(*this);
1912 if (Checker.Visit(Init))
1913 continue;
1914 }
1915
1916 Vars.push_back(RefExpr);
1917 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addDSA(VD, DE, OMPC_threadprivate);
1918 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1919 Context, SourceRange(Loc, Loc)));
1920 if (ASTMutationListener *ML = Context.getASTMutationListener())
1921 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1922 }
1923 OMPThreadPrivateDecl *D = nullptr;
1924 if (!Vars.empty()) {
1925 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1926 Vars);
1927 D->setAccess(AS_public);
1928 }
1929 return D;
1930}
1931
1932Sema::DeclGroupPtrTy
1933Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
1934 ArrayRef<OMPClause *> ClauseList) {
1935 OMPRequiresDecl *D = nullptr;
1936 if (!CurContext->isFileContext()) {
1937 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
1938 } else {
1939 D = CheckOMPRequiresDecl(Loc, ClauseList);
1940 if (D) {
1941 CurContext->addDecl(D);
1942 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addRequiresDecl(D);
1943 }
1944 }
1945 return DeclGroupPtrTy::make(DeclGroupRef(D));
1946}
1947
1948OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
1949 ArrayRef<OMPClause *> ClauseList) {
1950 if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->hasDuplicateRequiresClause(ClauseList))
1951 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
1952 ClauseList);
1953 return nullptr;
1954}
1955
1956static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
1957 const ValueDecl *D,
1958 const DSAStackTy::DSAVarData &DVar,
1959 bool IsLoopIterVar = false) {
1960 if (DVar.RefExpr) {
1961 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1962 << getOpenMPClauseName(DVar.CKind);
1963 return;
1964 }
1965 enum {
1966 PDSA_StaticMemberShared,
1967 PDSA_StaticLocalVarShared,
1968 PDSA_LoopIterVarPrivate,
1969 PDSA_LoopIterVarLinear,
1970 PDSA_LoopIterVarLastprivate,
1971 PDSA_ConstVarShared,
1972 PDSA_GlobalVarShared,
1973 PDSA_TaskVarFirstprivate,
1974 PDSA_LocalVarPrivate,
1975 PDSA_Implicit
1976 } Reason = PDSA_Implicit;
1977 bool ReportHint = false;
1978 auto ReportLoc = D->getLocation();
1979 auto *VD = dyn_cast<VarDecl>(D);
1980 if (IsLoopIterVar) {
1981 if (DVar.CKind == OMPC_private)
1982 Reason = PDSA_LoopIterVarPrivate;
1983 else if (DVar.CKind == OMPC_lastprivate)
1984 Reason = PDSA_LoopIterVarLastprivate;
1985 else
1986 Reason = PDSA_LoopIterVarLinear;
1987 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1988 DVar.CKind == OMPC_firstprivate) {
1989 Reason = PDSA_TaskVarFirstprivate;
1990 ReportLoc = DVar.ImplicitDSALoc;
1991 } else if (VD && VD->isStaticLocal())
1992 Reason = PDSA_StaticLocalVarShared;
1993 else if (VD && VD->isStaticDataMember())
1994 Reason = PDSA_StaticMemberShared;
1995 else if (VD && VD->isFileVarDecl())
1996 Reason = PDSA_GlobalVarShared;
1997 else if (D->getType().isConstant(SemaRef.getASTContext()))
1998 Reason = PDSA_ConstVarShared;
1999 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2000 ReportHint = true;
2001 Reason = PDSA_LocalVarPrivate;
2002 }
2003 if (Reason != PDSA_Implicit) {
2004 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2005 << Reason << ReportHint
2006 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2007 } else if (DVar.ImplicitDSALoc.isValid()) {
2008 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2009 << getOpenMPClauseName(DVar.CKind);
2010 }
2011}
2012
2013namespace {
2014class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2015 DSAStackTy *Stack;
2016 Sema &SemaRef;
2017 bool ErrorFound = false;
2018 CapturedStmt *CS = nullptr;
2019 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2020 llvm::SmallVector<Expr *, 4> ImplicitMap;
2021 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2022 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2023
2024public:
2025 void VisitDeclRefExpr(DeclRefExpr *E) {
2026 if (E->isTypeDependent() || E->isValueDependent() ||
2027 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2028 return;
2029 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2030 VD = VD->getCanonicalDecl();
2031 // Skip internally declared variables.
2032 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
2033 return;
2034
2035 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2036 // Check if the variable has explicit DSA set and stop analysis if it so.
2037 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2038 return;
2039
2040 // Skip internally declared static variables.
2041 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
2042 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2043 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
2044 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2045 return;
2046
2047 SourceLocation ELoc = E->getExprLoc();
2048 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2049 // The default(none) clause requires that each variable that is referenced
2050 // in the construct, and does not have a predetermined data-sharing
2051 // attribute, must have its data-sharing attribute explicitly determined
2052 // by being listed in a data-sharing attribute clause.
2053 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2054 isParallelOrTaskRegion(DKind) &&
2055 VarsWithInheritedDSA.count(VD) == 0) {
2056 VarsWithInheritedDSA[VD] = E;
2057 return;
2058 }
2059
2060 if (isOpenMPTargetExecutionDirective(DKind) &&
2061 !Stack->isLoopControlVariable(VD).first) {
2062 if (!Stack->checkMappableExprComponentListsForDecl(
2063 VD, /*CurrentRegionOnly=*/true,
2064 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2065 StackComponents,
2066 OpenMPClauseKind) {
2067 // Variable is used if it has been marked as an array, array
2068 // section or the variable iself.
2069 return StackComponents.size() == 1 ||
2070 std::all_of(
2071 std::next(StackComponents.rbegin()),
2072 StackComponents.rend(),
2073 [](const OMPClauseMappableExprCommon::
2074 MappableComponent &MC) {
2075 return MC.getAssociatedDeclaration() ==
2076 nullptr &&
2077 (isa<OMPArraySectionExpr>(
2078 MC.getAssociatedExpression()) ||
2079 isa<ArraySubscriptExpr>(
2080 MC.getAssociatedExpression()));
2081 });
2082 })) {
2083 bool IsFirstprivate = false;
2084 // By default lambdas are captured as firstprivates.
2085 if (const auto *RD =
2086 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2087 IsFirstprivate = RD->isLambda();
2088 IsFirstprivate =
2089 IsFirstprivate ||
2090 (VD->getType().getNonReferenceType()->isScalarType() &&
2091 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2092 if (IsFirstprivate)
2093 ImplicitFirstprivate.emplace_back(E);
2094 else
2095 ImplicitMap.emplace_back(E);
2096 return;
2097 }
2098 }
2099
2100 // OpenMP [2.9.3.6, Restrictions, p.2]
2101 // A list item that appears in a reduction clause of the innermost
2102 // enclosing worksharing or parallel construct may not be accessed in an
2103 // explicit task.
2104 DVar = Stack->hasInnermostDSA(
2105 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2106 [](OpenMPDirectiveKind K) {
2107 return isOpenMPParallelDirective(K) ||
2108 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2109 },
2110 /*FromParent=*/true);
2111 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2112 ErrorFound = true;
2113 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2114 reportOriginalDsa(SemaRef, Stack, VD, DVar);
2115 return;
2116 }
2117
2118 // Define implicit data-sharing attributes for task.
2119 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2120 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2121 !Stack->isLoopControlVariable(VD).first)
2122 ImplicitFirstprivate.push_back(E);
2123 }
2124 }
2125 void VisitMemberExpr(MemberExpr *E) {
2126 if (E->isTypeDependent() || E->isValueDependent() ||
2127 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
2128 return;
2129 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2130 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2131 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2132 if (!FD)
2133 return;
2134 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2135 // Check if the variable has explicit DSA set and stop analysis if it
2136 // so.
2137 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2138 return;
2139
2140 if (isOpenMPTargetExecutionDirective(DKind) &&
2141 !Stack->isLoopControlVariable(FD).first &&
2142 !Stack->checkMappableExprComponentListsForDecl(
2143 FD, /*CurrentRegionOnly=*/true,
2144 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
2145 StackComponents,
2146 OpenMPClauseKind) {
2147 return isa<CXXThisExpr>(
2148 cast<MemberExpr>(
2149 StackComponents.back().getAssociatedExpression())
2150 ->getBase()
2151 ->IgnoreParens());
2152 })) {
2153 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2154 // A bit-field cannot appear in a map clause.
2155 //
2156 if (FD->isBitField())
2157 return;
2158 ImplicitMap.emplace_back(E);
2159 return;
2160 }
2161
2162 SourceLocation ELoc = E->getExprLoc();
2163 // OpenMP [2.9.3.6, Restrictions, p.2]
2164 // A list item that appears in a reduction clause of the innermost
2165 // enclosing worksharing or parallel construct may not be accessed in
2166 // an explicit task.
2167 DVar = Stack->hasInnermostDSA(
2168 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2169 [](OpenMPDirectiveKind K) {
2170 return isOpenMPParallelDirective(K) ||
2171 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2172 },
2173 /*FromParent=*/true);
2174 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2175 ErrorFound = true;
2176 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2177 reportOriginalDsa(SemaRef, Stack, FD, DVar);
2178 return;
2179 }
2180
2181 // Define implicit data-sharing attributes for task.
2182 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2183 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2184 !Stack->isLoopControlVariable(FD).first) {
2185 // Check if there is a captured expression for the current field in the
2186 // region. Do not mark it as firstprivate unless there is no captured
2187 // expression.
2188 // TODO: try to make it firstprivate.
2189 if (DVar.CKind != OMPC_unknown)
2190 ImplicitFirstprivate.push_back(E);
2191 }
2192 return;
2193 }
2194 if (isOpenMPTargetExecutionDirective(DKind)) {
2195 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2196 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2197 /*NoDiagnose=*/true))
2198 return;
2199 const auto *VD = cast<ValueDecl>(
2200 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2201 if (!Stack->checkMappableExprComponentListsForDecl(
2202 VD, /*CurrentRegionOnly=*/true,
2203 [&CurComponents](
2204 OMPClauseMappableExprCommon::MappableExprComponentListRef
2205 StackComponents,
2206 OpenMPClauseKind) {
2207 auto CCI = CurComponents.rbegin();
2208 auto CCE = CurComponents.rend();
2209 for (const auto &SC : llvm::reverse(StackComponents)) {
2210 // Do both expressions have the same kind?
2211 if (CCI->getAssociatedExpression()->getStmtClass() !=
2212 SC.getAssociatedExpression()->getStmtClass())
2213 if (!(isa<OMPArraySectionExpr>(
2214 SC.getAssociatedExpression()) &&
2215 isa<ArraySubscriptExpr>(
2216 CCI->getAssociatedExpression())))
2217 return false;
2218
2219 const Decl *CCD = CCI->getAssociatedDeclaration();
2220 const Decl *SCD = SC.getAssociatedDeclaration();
2221 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2222 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2223 if (SCD != CCD)
2224 return false;
2225 std::advance(CCI, 1);
2226 if (CCI == CCE)
2227 break;
2228 }
2229 return true;
2230 })) {
2231 Visit(E->getBase());
2232 }
2233 } else {
2234 Visit(E->getBase());
2235 }
2236 }
2237 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2238 for (OMPClause *C : S->clauses()) {
2239 // Skip analysis of arguments of implicitly defined firstprivate clause
2240 // for task|target directives.
2241 // Skip analysis of arguments of implicitly defined map clause for target
2242 // directives.
2243 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2244 C->isImplicit())) {
2245 for (Stmt *CC : C->children()) {
2246 if (CC)
2247 Visit(CC);
2248 }
2249 }
2250 }
2251 }
2252 void VisitStmt(Stmt *S) {
2253 for (Stmt *C : S->children()) {
2254 if (C) {
2255 if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) {
2256 // Check implicitly captured vriables in the task-based directives to
2257 // check if they must be firstprivatized.
2258 if (!OED->hasAssociatedStmt())
2259 continue;
2260 const Stmt *AS = OED->getAssociatedStmt();
2261 if (!AS)
2262 continue;
2263 for (const CapturedStmt::Capture &Cap :
2264 cast<CapturedStmt>(AS)->captures()) {
2265 if (Cap.capturesVariable()) {
2266 DeclRefExpr *DRE = buildDeclRefExpr(
2267 SemaRef, Cap.getCapturedVar(),
2268 Cap.getCapturedVar()->getType().getNonLValueExprType(
2269 SemaRef.Context),
2270 Cap.getLocation(),
2271 /*RefersToCapture=*/true);
2272 Visit(DRE);
2273 }
2274 }
2275 } else {
2276 Visit(C);
2277 }
2278 }
2279 }
2280 }
2281
2282 bool isErrorFound() const { return ErrorFound; }
2283 ArrayRef<Expr *> getImplicitFirstprivate() const {
2284 return ImplicitFirstprivate;
2285 }
2286 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2287 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2288 return VarsWithInheritedDSA;
2289 }
2290
2291 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2292 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2293};
2294} // namespace
2295
2296void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2297 switch (DKind) {
2298 case OMPD_parallel:
2299 case OMPD_parallel_for:
2300 case OMPD_parallel_for_simd:
2301 case OMPD_parallel_sections:
2302 case OMPD_teams:
2303 case OMPD_teams_distribute:
2304 case OMPD_teams_distribute_simd: {
2305 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2306 QualType KmpInt32PtrTy =
2307 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2308 Sema::CapturedParamNameType Params[] = {
2309 std::make_pair(".global_tid.", KmpInt32PtrTy),
2310 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2311 std::make_pair(StringRef(), QualType()) // __context with shared vars
2312 };
2313 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2314 Params);
2315 break;
2316 }
2317 case OMPD_target_teams:
2318 case OMPD_target_parallel:
2319 case OMPD_target_parallel_for:
2320 case OMPD_target_parallel_for_simd:
2321 case OMPD_target_teams_distribute:
2322 case OMPD_target_teams_distribute_simd: {
2323 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2324 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2325 QualType KmpInt32PtrTy =
2326 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2327 QualType Args[] = {VoidPtrTy};
2328 FunctionProtoType::ExtProtoInfo EPI;
2329 EPI.Variadic = true;
2330 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2331 Sema::CapturedParamNameType Params[] = {
2332 std::make_pair(".global_tid.", KmpInt32Ty),
2333 std::make_pair(".part_id.", KmpInt32PtrTy),
2334 std::make_pair(".privates.", VoidPtrTy),
2335 std::make_pair(
2336 ".copy_fn.",
2337 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2338 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2339 std::make_pair(StringRef(), QualType()) // __context with shared vars
2340 };
2341 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2342 Params);
2343 // Mark this captured region as inlined, because we don't use outlined
2344 // function directly.
2345 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2346 AlwaysInlineAttr::CreateImplicit(
2347 Context, AlwaysInlineAttr::Keyword_forceinline));
2348 Sema::CapturedParamNameType ParamsTarget[] = {
2349 std::make_pair(StringRef(), QualType()) // __context with shared vars
2350 };
2351 // Start a captured region for 'target' with no implicit parameters.
2352 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2353 ParamsTarget);
2354 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2355 std::make_pair(".global_tid.", KmpInt32PtrTy),
2356 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2357 std::make_pair(StringRef(), QualType()) // __context with shared vars
2358 };
2359 // Start a captured region for 'teams' or 'parallel'. Both regions have
2360 // the same implicit parameters.
2361 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2362 ParamsTeamsOrParallel);
2363 break;
2364 }
2365 case OMPD_target:
2366 case OMPD_target_simd: {
2367 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2368 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2369 QualType KmpInt32PtrTy =
2370 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2371 QualType Args[] = {VoidPtrTy};
2372 FunctionProtoType::ExtProtoInfo EPI;
2373 EPI.Variadic = true;
2374 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2375 Sema::CapturedParamNameType Params[] = {
2376 std::make_pair(".global_tid.", KmpInt32Ty),
2377 std::make_pair(".part_id.", KmpInt32PtrTy),
2378 std::make_pair(".privates.", VoidPtrTy),
2379 std::make_pair(
2380 ".copy_fn.",
2381 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2382 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2383 std::make_pair(StringRef(), QualType()) // __context with shared vars
2384 };
2385 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2386 Params);
2387 // Mark this captured region as inlined, because we don't use outlined
2388 // function directly.
2389 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2390 AlwaysInlineAttr::CreateImplicit(
2391 Context, AlwaysInlineAttr::Keyword_forceinline));
2392 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2393 std::make_pair(StringRef(), QualType()));
2394 break;
2395 }
2396 case OMPD_simd:
2397 case OMPD_for:
2398 case OMPD_for_simd:
2399 case OMPD_sections:
2400 case OMPD_section:
2401 case OMPD_single:
2402 case OMPD_master:
2403 case OMPD_critical:
2404 case OMPD_taskgroup:
2405 case OMPD_distribute:
2406 case OMPD_distribute_simd:
2407 case OMPD_ordered:
2408 case OMPD_atomic:
2409 case OMPD_target_data: {
2410 Sema::CapturedParamNameType Params[] = {
2411 std::make_pair(StringRef(), QualType()) // __context with shared vars
2412 };
2413 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2414 Params);
2415 break;
2416 }
2417 case OMPD_task: {
2418 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2419 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2420 QualType KmpInt32PtrTy =
2421 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2422 QualType Args[] = {VoidPtrTy};
2423 FunctionProtoType::ExtProtoInfo EPI;
2424 EPI.Variadic = true;
2425 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2426 Sema::CapturedParamNameType Params[] = {
2427 std::make_pair(".global_tid.", KmpInt32Ty),
2428 std::make_pair(".part_id.", KmpInt32PtrTy),
2429 std::make_pair(".privates.", VoidPtrTy),
2430 std::make_pair(
2431 ".copy_fn.",
2432 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2433 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2434 std::make_pair(StringRef(), QualType()) // __context with shared vars
2435 };
2436 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2437 Params);
2438 // Mark this captured region as inlined, because we don't use outlined
2439 // function directly.
2440 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2441 AlwaysInlineAttr::CreateImplicit(
2442 Context, AlwaysInlineAttr::Keyword_forceinline));
2443 break;
2444 }
2445 case OMPD_taskloop:
2446 case OMPD_taskloop_simd: {
2447 QualType KmpInt32Ty =
2448 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
2449 .withConst();
2450 QualType KmpUInt64Ty =
2451 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
2452 .withConst();
2453 QualType KmpInt64Ty =
2454 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
2455 .withConst();
2456 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2457 QualType KmpInt32PtrTy =
2458 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2459 QualType Args[] = {VoidPtrTy};
2460 FunctionProtoType::ExtProtoInfo EPI;
2461 EPI.Variadic = true;
2462 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2463 Sema::CapturedParamNameType Params[] = {
2464 std::make_pair(".global_tid.", KmpInt32Ty),
2465 std::make_pair(".part_id.", KmpInt32PtrTy),
2466 std::make_pair(".privates.", VoidPtrTy),
2467 std::make_pair(
2468 ".copy_fn.",
2469 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2470 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2471 std::make_pair(".lb.", KmpUInt64Ty),
2472 std::make_pair(".ub.", KmpUInt64Ty),
2473 std::make_pair(".st.", KmpInt64Ty),
2474 std::make_pair(".liter.", KmpInt32Ty),
2475 std::make_pair(".reductions.", VoidPtrTy),
2476 std::make_pair(StringRef(), QualType()) // __context with shared vars
2477 };
2478 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2479 Params);
2480 // Mark this captured region as inlined, because we don't use outlined
2481 // function directly.
2482 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2483 AlwaysInlineAttr::CreateImplicit(
2484 Context, AlwaysInlineAttr::Keyword_forceinline));
2485 break;
2486 }
2487 case OMPD_distribute_parallel_for_simd:
2488 case OMPD_distribute_parallel_for: {
2489 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2490 QualType KmpInt32PtrTy =
2491 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2492 Sema::CapturedParamNameType Params[] = {
2493 std::make_pair(".global_tid.", KmpInt32PtrTy),
2494 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2495 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2496 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2497 std::make_pair(StringRef(), QualType()) // __context with shared vars
2498 };
2499 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2500 Params);
2501 break;
2502 }
2503 case OMPD_target_teams_distribute_parallel_for:
2504 case OMPD_target_teams_distribute_parallel_for_simd: {
2505 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2506 QualType KmpInt32PtrTy =
2507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2508 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2509
2510 QualType Args[] = {VoidPtrTy};
2511 FunctionProtoType::ExtProtoInfo EPI;
2512 EPI.Variadic = true;
2513 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2514 Sema::CapturedParamNameType Params[] = {
2515 std::make_pair(".global_tid.", KmpInt32Ty),
2516 std::make_pair(".part_id.", KmpInt32PtrTy),
2517 std::make_pair(".privates.", VoidPtrTy),
2518 std::make_pair(
2519 ".copy_fn.",
2520 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2521 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2522 std::make_pair(StringRef(), QualType()) // __context with shared vars
2523 };
2524 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2525 Params);
2526 // Mark this captured region as inlined, because we don't use outlined
2527 // function directly.
2528 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2529 AlwaysInlineAttr::CreateImplicit(
2530 Context, AlwaysInlineAttr::Keyword_forceinline));
2531 Sema::CapturedParamNameType ParamsTarget[] = {
2532 std::make_pair(StringRef(), QualType()) // __context with shared vars
2533 };
2534 // Start a captured region for 'target' with no implicit parameters.
2535 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2536 ParamsTarget);
2537
2538 Sema::CapturedParamNameType ParamsTeams[] = {
2539 std::make_pair(".global_tid.", KmpInt32PtrTy),
2540 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2541 std::make_pair(StringRef(), QualType()) // __context with shared vars
2542 };
2543 // Start a captured region for 'target' with no implicit parameters.
2544 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2545 ParamsTeams);
2546
2547 Sema::CapturedParamNameType ParamsParallel[] = {
2548 std::make_pair(".global_tid.", KmpInt32PtrTy),
2549 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2550 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2551 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2552 std::make_pair(StringRef(), QualType()) // __context with shared vars
2553 };
2554 // Start a captured region for 'teams' or 'parallel'. Both regions have
2555 // the same implicit parameters.
2556 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2557 ParamsParallel);
2558 break;
2559 }
2560
2561 case OMPD_teams_distribute_parallel_for:
2562 case OMPD_teams_distribute_parallel_for_simd: {
2563 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2564 QualType KmpInt32PtrTy =
2565 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2566
2567 Sema::CapturedParamNameType ParamsTeams[] = {
2568 std::make_pair(".global_tid.", KmpInt32PtrTy),
2569 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2570 std::make_pair(StringRef(), QualType()) // __context with shared vars
2571 };
2572 // Start a captured region for 'target' with no implicit parameters.
2573 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2574 ParamsTeams);
2575
2576 Sema::CapturedParamNameType ParamsParallel[] = {
2577 std::make_pair(".global_tid.", KmpInt32PtrTy),
2578 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2579 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2580 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2581 std::make_pair(StringRef(), QualType()) // __context with shared vars
2582 };
2583 // Start a captured region for 'teams' or 'parallel'. Both regions have
2584 // the same implicit parameters.
2585 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2586 ParamsParallel);
2587 break;
2588 }
2589 case OMPD_target_update:
2590 case OMPD_target_enter_data:
2591 case OMPD_target_exit_data: {
2592 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2593 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2594 QualType KmpInt32PtrTy =
2595 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2596 QualType Args[] = {VoidPtrTy};
2597 FunctionProtoType::ExtProtoInfo EPI;
2598 EPI.Variadic = true;
2599 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2600 Sema::CapturedParamNameType Params[] = {
2601 std::make_pair(".global_tid.", KmpInt32Ty),
2602 std::make_pair(".part_id.", KmpInt32PtrTy),
2603 std::make_pair(".privates.", VoidPtrTy),
2604 std::make_pair(
2605 ".copy_fn.",
2606 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2607 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2608 std::make_pair(StringRef(), QualType()) // __context with shared vars
2609 };
2610 ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getConstructLoc(), CurScope, CR_OpenMP,
2611 Params);
2612 // Mark this captured region as inlined, because we don't use outlined
2613 // function directly.
2614 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2615 AlwaysInlineAttr::CreateImplicit(
2616 Context, AlwaysInlineAttr::Keyword_forceinline));
2617 break;
2618 }
2619 case OMPD_threadprivate:
2620 case OMPD_taskyield:
2621 case OMPD_barrier:
2622 case OMPD_taskwait:
2623 case OMPD_cancellation_point:
2624 case OMPD_cancel:
2625 case OMPD_flush:
2626 case OMPD_declare_reduction:
2627 case OMPD_declare_simd:
2628 case OMPD_declare_target:
2629 case OMPD_end_declare_target:
2630 case OMPD_requires:
2631 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2631)
;
2632 case OMPD_unknown:
2633 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2633)
;
2634 }
2635}
2636
2637int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2638 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2639 getOpenMPCaptureRegions(CaptureRegions, DKind);
2640 return CaptureRegions.size();
2641}
2642
2643static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2644 Expr *CaptureExpr, bool WithInit,
2645 bool AsExpression) {
2646 assert(CaptureExpr)((CaptureExpr) ? static_cast<void> (0) : __assert_fail (
"CaptureExpr", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 2646, __PRETTY_FUNCTION__))
;
2647 ASTContext &C = S.getASTContext();
2648 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2649 QualType Ty = Init->getType();
2650 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2651 if (S.getLangOpts().CPlusPlus) {
2652 Ty = C.getLValueReferenceType(Ty);
2653 } else {
2654 Ty = C.getPointerType(Ty);
2655 ExprResult Res =
2656 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2657 if (!Res.isUsable())
2658 return nullptr;
2659 Init = Res.get();
2660 }
2661 WithInit = true;
2662 }
2663 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2664 CaptureExpr->getBeginLoc());
2665 if (!WithInit)
2666 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2667 S.CurContext->addHiddenDecl(CED);
2668 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2669 return CED;
2670}
2671
2672static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2673 bool WithInit) {
2674 OMPCapturedExprDecl *CD;
2675 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
2676 CD = cast<OMPCapturedExprDecl>(VD);
2677 else
2678 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2679 /*AsExpression=*/false);
2680 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2681 CaptureExpr->getExprLoc());
2682}
2683
2684static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2685 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2686 if (!Ref) {
2687 OMPCapturedExprDecl *CD = buildCaptureDecl(
2688 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2689 /*WithInit=*/true, /*AsExpression=*/true);
2690 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2691 CaptureExpr->getExprLoc());
2692 }
2693 ExprResult Res = Ref;
2694 if (!S.getLangOpts().CPlusPlus &&
2695 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2696 Ref->getType()->isPointerType()) {
2697 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2698 if (!Res.isUsable())
2699 return ExprError();
2700 }
2701 return S.DefaultLvalueConversion(Res.get());
2702}
2703
2704namespace {
2705// OpenMP directives parsed in this section are represented as a
2706// CapturedStatement with an associated statement. If a syntax error
2707// is detected during the parsing of the associated statement, the
2708// compiler must abort processing and close the CapturedStatement.
2709//
2710// Combined directives such as 'target parallel' have more than one
2711// nested CapturedStatements. This RAII ensures that we unwind out
2712// of all the nested CapturedStatements when an error is found.
2713class CaptureRegionUnwinderRAII {
2714private:
2715 Sema &S;
2716 bool &ErrorFound;
2717 OpenMPDirectiveKind DKind = OMPD_unknown;
2718
2719public:
2720 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2721 OpenMPDirectiveKind DKind)
2722 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2723 ~CaptureRegionUnwinderRAII() {
2724 if (ErrorFound) {
2725 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2726 while (--ThisCaptureLevel >= 0)
2727 S.ActOnCapturedRegionError();
2728 }
2729 }
2730};
2731} // namespace
2732
2733StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2734 ArrayRef<OMPClause *> Clauses) {
2735 bool ErrorFound = false;
2736 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2737 *this, ErrorFound, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2738 if (!S.isUsable()) {
2739 ErrorFound = true;
2740 return StmtError();
2741 }
2742
2743 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2744 getOpenMPCaptureRegions(CaptureRegions, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2745 OMPOrderedClause *OC = nullptr;
2746 OMPScheduleClause *SC = nullptr;
2747 SmallVector<const OMPLinearClause *, 4> LCs;
2748 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
2749 // This is required for proper codegen.
2750 for (OMPClause *Clause : Clauses) {
2751 if (isOpenMPTaskingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2752 Clause->getClauseKind() == OMPC_in_reduction) {
2753 // Capture taskgroup task_reduction descriptors inside the tasking regions
2754 // with the corresponding in_reduction items.
2755 auto *IRC = cast<OMPInReductionClause>(Clause);
2756 for (Expr *E : IRC->taskgroup_descriptors())
2757 if (E)
2758 MarkDeclarationsReferencedInExpr(E);
2759 }
2760 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2761 Clause->getClauseKind() == OMPC_copyprivate ||
2762 (getLangOpts().OpenMPUseTLS &&
2763 getASTContext().getTargetInfo().isTLSSupported() &&
2764 Clause->getClauseKind() == OMPC_copyin)) {
2765 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2766 // Mark all variables in private list clauses as used in inner region.
2767 for (Stmt *VarRef : Clause->children()) {
2768 if (auto *E = cast_or_null<Expr>(VarRef)) {
2769 MarkDeclarationsReferencedInExpr(E);
2770 }
2771 }
2772 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setForceVarCapturing(/*V=*/false);
2773 } else if (CaptureRegions.size() > 1 ||
2774 CaptureRegions.back() != OMPD_unknown) {
2775 if (auto *C = OMPClauseWithPreInit::get(Clause))
2776 PICs.push_back(C);
2777 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2778 if (Expr *E = C->getPostUpdateExpr())
2779 MarkDeclarationsReferencedInExpr(E);
2780 }
2781 }
2782 if (Clause->getClauseKind() == OMPC_schedule)
2783 SC = cast<OMPScheduleClause>(Clause);
2784 else if (Clause->getClauseKind() == OMPC_ordered)
2785 OC = cast<OMPOrderedClause>(Clause);
2786 else if (Clause->getClauseKind() == OMPC_linear)
2787 LCs.push_back(cast<OMPLinearClause>(Clause));
2788 }
2789 // OpenMP, 2.7.1 Loop Construct, Restrictions
2790 // The nonmonotonic modifier cannot be specified if an ordered clause is
2791 // specified.
2792 if (SC &&
2793 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2794 SC->getSecondScheduleModifier() ==
2795 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2796 OC) {
2797 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2798 ? SC->getFirstScheduleModifierLoc()
2799 : SC->getSecondScheduleModifierLoc(),
2800 diag::err_omp_schedule_nonmonotonic_ordered)
2801 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2802 ErrorFound = true;
2803 }
2804 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2805 for (const OMPLinearClause *C : LCs) {
2806 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
2807 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2808 }
2809 ErrorFound = true;
2810 }
2811 if (isOpenMPWorksharingDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) &&
2812 isOpenMPSimdDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective()) && OC &&
2813 OC->getNumForLoops()) {
2814 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
2815 << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective());
2816 ErrorFound = true;
2817 }
2818 if (ErrorFound) {
2819 return StmtError();
2820 }
2821 StmtResult SR = S;
2822 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2823 // Mark all variables in private list clauses as used in inner region.
2824 // Required for proper codegen of combined directives.
2825 // TODO: add processing for other clauses.
2826 if (ThisCaptureRegion != OMPD_unknown) {
2827 for (const clang::OMPClauseWithPreInit *C : PICs) {
2828 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2829 // Find the particular capture region for the clause if the
2830 // directive is a combined one with multiple capture regions.
2831 // If the directive is not a combined one, the capture region
2832 // associated with the clause is OMPD_unknown and is generated
2833 // only once.
2834 if (CaptureRegion == ThisCaptureRegion ||
2835 CaptureRegion == OMPD_unknown) {
2836 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2837 for (Decl *D : DS->decls())
2838 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2839 }
2840 }
2841 }
2842 }
2843 SR = ActOnCapturedRegionEnd(SR.get());
2844 }
2845 return SR;
2846}
2847
2848static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2849 OpenMPDirectiveKind CancelRegion,
2850 SourceLocation StartLoc) {
2851 // CancelRegion is only needed for cancel and cancellation_point.
2852 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2853 return false;
2854
2855 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2856 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2857 return false;
2858
2859 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2860 << getOpenMPDirectiveName(CancelRegion);
2861 return true;
2862}
2863
2864static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
2865 OpenMPDirectiveKind CurrentRegion,
2866 const DeclarationNameInfo &CurrentName,
2867 OpenMPDirectiveKind CancelRegion,
2868 SourceLocation StartLoc) {
2869 if (Stack->getCurScope()) {
2870 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
2871 OpenMPDirectiveKind OffendingRegion = ParentRegion;
2872 bool NestingProhibited = false;
2873 bool CloseNesting = true;
2874 bool OrphanSeen = false;
2875 enum {
2876 NoRecommend,
2877 ShouldBeInParallelRegion,
2878 ShouldBeInOrderedRegion,
2879 ShouldBeInTargetRegion,
2880 ShouldBeInTeamsRegion
2881 } Recommend = NoRecommend;
2882 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2883 // OpenMP [2.16, Nesting of Regions]
2884 // OpenMP constructs may not be nested inside a simd region.
2885 // OpenMP [2.8.1,simd Construct, Restrictions]
2886 // An ordered construct with the simd clause is the only OpenMP
2887 // construct that can appear in the simd region.
2888 // Allowing a SIMD construct nested in another SIMD construct is an
2889 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2890 // message.
2891 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2892 ? diag::err_omp_prohibited_region_simd
2893 : diag::warn_omp_nesting_simd);
2894 return CurrentRegion != OMPD_simd;
2895 }
2896 if (ParentRegion == OMPD_atomic) {
2897 // OpenMP [2.16, Nesting of Regions]
2898 // OpenMP constructs may not be nested inside an atomic region.
2899 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2900 return true;
2901 }
2902 if (CurrentRegion == OMPD_section) {
2903 // OpenMP [2.7.2, sections Construct, Restrictions]
2904 // Orphaned section directives are prohibited. That is, the section
2905 // directives must appear within the sections construct and must not be
2906 // encountered elsewhere in the sections region.
2907 if (ParentRegion != OMPD_sections &&
2908 ParentRegion != OMPD_parallel_sections) {
2909 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2910 << (ParentRegion != OMPD_unknown)
2911 << getOpenMPDirectiveName(ParentRegion);
2912 return true;
2913 }
2914 return false;
2915 }
2916 // Allow some constructs (except teams) to be orphaned (they could be
2917 // used in functions, called from OpenMP regions with the required
2918 // preconditions).
2919 if (ParentRegion == OMPD_unknown &&
2920 !isOpenMPNestingTeamsDirective(CurrentRegion))
2921 return false;
2922 if (CurrentRegion == OMPD_cancellation_point ||
2923 CurrentRegion == OMPD_cancel) {
2924 // OpenMP [2.16, Nesting of Regions]
2925 // A cancellation point construct for which construct-type-clause is
2926 // taskgroup must be nested inside a task construct. A cancellation
2927 // point construct for which construct-type-clause is not taskgroup must
2928 // be closely nested inside an OpenMP construct that matches the type
2929 // specified in construct-type-clause.
2930 // A cancel construct for which construct-type-clause is taskgroup must be
2931 // nested inside a task construct. A cancel construct for which
2932 // construct-type-clause is not taskgroup must be closely nested inside an
2933 // OpenMP construct that matches the type specified in
2934 // construct-type-clause.
2935 NestingProhibited =
2936 !((CancelRegion == OMPD_parallel &&
2937 (ParentRegion == OMPD_parallel ||
2938 ParentRegion == OMPD_target_parallel)) ||
2939 (CancelRegion == OMPD_for &&
2940 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2941 ParentRegion == OMPD_target_parallel_for ||
2942 ParentRegion == OMPD_distribute_parallel_for ||
2943 ParentRegion == OMPD_teams_distribute_parallel_for ||
2944 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2945 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2946 (CancelRegion == OMPD_sections &&
2947 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2948 ParentRegion == OMPD_parallel_sections)));
2949 } else if (CurrentRegion == OMPD_master) {
2950 // OpenMP [2.16, Nesting of Regions]
2951 // A master region may not be closely nested inside a worksharing,
2952 // atomic, or explicit task region.
2953 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2954 isOpenMPTaskingDirective(ParentRegion);
2955 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2956 // OpenMP [2.16, Nesting of Regions]
2957 // A critical region may not be nested (closely or otherwise) inside a
2958 // critical region with the same name. Note that this restriction is not
2959 // sufficient to prevent deadlock.
2960 SourceLocation PreviousCriticalLoc;
2961 bool DeadLock = Stack->hasDirective(
2962 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2963 const DeclarationNameInfo &DNI,
2964 SourceLocation Loc) {
2965 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2966 PreviousCriticalLoc = Loc;
2967 return true;
2968 }
2969 return false;
2970 },
2971 false /* skip top directive */);
2972 if (DeadLock) {
2973 SemaRef.Diag(StartLoc,
2974 diag::err_omp_prohibited_region_critical_same_name)
2975 << CurrentName.getName();
2976 if (PreviousCriticalLoc.isValid())
2977 SemaRef.Diag(PreviousCriticalLoc,
2978 diag::note_omp_previous_critical_region);
2979 return true;
2980 }
2981 } else if (CurrentRegion == OMPD_barrier) {
2982 // OpenMP [2.16, Nesting of Regions]
2983 // A barrier region may not be closely nested inside a worksharing,
2984 // explicit task, critical, ordered, atomic, or master region.
2985 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2986 isOpenMPTaskingDirective(ParentRegion) ||
2987 ParentRegion == OMPD_master ||
2988 ParentRegion == OMPD_critical ||
2989 ParentRegion == OMPD_ordered;
2990 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2991 !isOpenMPParallelDirective(CurrentRegion) &&
2992 !isOpenMPTeamsDirective(CurrentRegion)) {
2993 // OpenMP [2.16, Nesting of Regions]
2994 // A worksharing region may not be closely nested inside a worksharing,
2995 // explicit task, critical, ordered, atomic, or master region.
2996 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2997 isOpenMPTaskingDirective(ParentRegion) ||
2998 ParentRegion == OMPD_master ||
2999 ParentRegion == OMPD_critical ||
3000 ParentRegion == OMPD_ordered;
3001 Recommend = ShouldBeInParallelRegion;
3002 } else if (CurrentRegion == OMPD_ordered) {
3003 // OpenMP [2.16, Nesting of Regions]
3004 // An ordered region may not be closely nested inside a critical,
3005 // atomic, or explicit task region.
3006 // An ordered region must be closely nested inside a loop region (or
3007 // parallel loop region) with an ordered clause.
3008 // OpenMP [2.8.1,simd Construct, Restrictions]
3009 // An ordered construct with the simd clause is the only OpenMP construct
3010 // that can appear in the simd region.
3011 NestingProhibited = ParentRegion == OMPD_critical ||
3012 isOpenMPTaskingDirective(ParentRegion) ||
3013 !(isOpenMPSimdDirective(ParentRegion) ||
3014 Stack->isParentOrderedRegion());
3015 Recommend = ShouldBeInOrderedRegion;
3016 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
3017 // OpenMP [2.16, Nesting of Regions]
3018 // If specified, a teams construct must be contained within a target
3019 // construct.
3020 NestingProhibited = ParentRegion != OMPD_target;
3021 OrphanSeen = ParentRegion == OMPD_unknown;
3022 Recommend = ShouldBeInTargetRegion;
3023 }
3024 if (!NestingProhibited &&
3025 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3026 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3027 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3028 // OpenMP [2.16, Nesting of Regions]
3029 // distribute, parallel, parallel sections, parallel workshare, and the
3030 // parallel loop and parallel loop SIMD constructs are the only OpenMP
3031 // constructs that can be closely nested in the teams region.
3032 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3033 !isOpenMPDistributeDirective(CurrentRegion);
3034 Recommend = ShouldBeInParallelRegion;
3035 }
3036 if (!NestingProhibited &&
3037 isOpenMPNestingDistributeDirective(CurrentRegion)) {
3038 // OpenMP 4.5 [2.17 Nesting of Regions]
3039 // The region associated with the distribute construct must be strictly
3040 // nested inside a teams region
3041 NestingProhibited =
3042 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3043 Recommend = ShouldBeInTeamsRegion;
3044 }
3045 if (!NestingProhibited &&
3046 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3047 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3048 // OpenMP 4.5 [2.17 Nesting of Regions]
3049 // If a target, target update, target data, target enter data, or
3050 // target exit data construct is encountered during execution of a
3051 // target region, the behavior is unspecified.
3052 NestingProhibited = Stack->hasDirective(
3053 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
3054 SourceLocation) {
3055 if (isOpenMPTargetExecutionDirective(K)) {
3056 OffendingRegion = K;
3057 return true;
3058 }
3059 return false;
3060 },
3061 false /* don't skip top directive */);
3062 CloseNesting = false;
3063 }
3064 if (NestingProhibited) {
3065 if (OrphanSeen) {
3066 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3067 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3068 } else {
3069 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3070 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3071 << Recommend << getOpenMPDirectiveName(CurrentRegion);
3072 }
3073 return true;
3074 }
3075 }
3076 return false;
3077}
3078
3079static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
3080 ArrayRef<OMPClause *> Clauses,
3081 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3082 bool ErrorFound = false;
3083 unsigned NamedModifiersNumber = 0;
3084 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
3085 OMPD_unknown + 1);
3086 SmallVector<SourceLocation, 4> NameModifierLoc;
3087 for (const OMPClause *C : Clauses) {
3088 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3089 // At most one if clause without a directive-name-modifier can appear on
3090 // the directive.
3091 OpenMPDirectiveKind CurNM = IC->getNameModifier();
3092 if (FoundNameModifiers[CurNM]) {
3093 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
3094 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3095 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3096 ErrorFound = true;
3097 } else if (CurNM != OMPD_unknown) {
3098 NameModifierLoc.push_back(IC->getNameModifierLoc());
3099 ++NamedModifiersNumber;
3100 }
3101 FoundNameModifiers[CurNM] = IC;
3102 if (CurNM == OMPD_unknown)
3103 continue;
3104 // Check if the specified name modifier is allowed for the current
3105 // directive.
3106 // At most one if clause with the particular directive-name-modifier can
3107 // appear on the directive.
3108 bool MatchFound = false;
3109 for (auto NM : AllowedNameModifiers) {
3110 if (CurNM == NM) {
3111 MatchFound = true;
3112 break;
3113 }
3114 }
3115 if (!MatchFound) {
3116 S.Diag(IC->getNameModifierLoc(),
3117 diag::err_omp_wrong_if_directive_name_modifier)
3118 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
3119 ErrorFound = true;
3120 }
3121 }
3122 }
3123 // If any if clause on the directive includes a directive-name-modifier then
3124 // all if clauses on the directive must include a directive-name-modifier.
3125 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3126 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3127 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
3128 diag::err_omp_no_more_if_clause);
3129 } else {
3130 std::string Values;
3131 std::string Sep(", ");
3132 unsigned AllowedCnt = 0;
3133 unsigned TotalAllowedNum =
3134 AllowedNameModifiers.size() - NamedModifiersNumber;
3135 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3136 ++Cnt) {
3137 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3138 if (!FoundNameModifiers[NM]) {
3139 Values += "'";
3140 Values += getOpenMPDirectiveName(NM);
3141 Values += "'";
3142 if (AllowedCnt + 2 == TotalAllowedNum)
3143 Values += " or ";
3144 else if (AllowedCnt + 1 != TotalAllowedNum)
3145 Values += Sep;
3146 ++AllowedCnt;
3147 }
3148 }
3149 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
3150 diag::err_omp_unnamed_if_clause)
3151 << (TotalAllowedNum > 1) << Values;
3152 }
3153 for (SourceLocation Loc : NameModifierLoc) {
3154 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3155 }
3156 ErrorFound = true;
3157 }
3158 return ErrorFound;
3159}
3160
3161StmtResult Sema::ActOnOpenMPExecutableDirective(
3162 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
3163 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3164 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3165 StmtResult Res = StmtError();
3166 // First check CancelRegion which is then used in checkNestingOfRegions.
3167 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3168 checkNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, Kind, DirName, CancelRegion,
3169 StartLoc))
3170 return StmtError();
3171
3172 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3173 VarsWithInheritedDSAType VarsWithInheritedDSA;
3174 bool ErrorFound = false;
3175 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3176 if (AStmt && !CurContext->isDependentContext()) {
3177 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3177, __PRETTY_FUNCTION__))
;
3178
3179 // Check default data sharing attributes for referenced variables.
3180 DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, *this, cast<CapturedStmt>(AStmt));
3181 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3182 Stmt *S = AStmt;
3183 while (--ThisCaptureLevel >= 0)
3184 S = cast<CapturedStmt>(S)->getCapturedStmt();
3185 DSAChecker.Visit(S);
3186 if (DSAChecker.isErrorFound())
3187 return StmtError();
3188 // Generate list of implicitly defined firstprivate variables.
3189 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3190
3191 SmallVector<Expr *, 4> ImplicitFirstprivates(
3192 DSAChecker.getImplicitFirstprivate().begin(),
3193 DSAChecker.getImplicitFirstprivate().end());
3194 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3195 DSAChecker.getImplicitMap().end());
3196 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3197 for (OMPClause *C : Clauses) {
3198 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3199 for (Expr *E : IRC->taskgroup_descriptors())
3200 if (E)
3201 ImplicitFirstprivates.emplace_back(E);
3202 }
3203 }
3204 if (!ImplicitFirstprivates.empty()) {
3205 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3206 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3207 SourceLocation())) {
3208 ClausesWithImplicit.push_back(Implicit);
3209 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3210 ImplicitFirstprivates.size();
3211 } else {
3212 ErrorFound = true;
3213 }
3214 }
3215 if (!ImplicitMaps.empty()) {
3216 if (OMPClause *Implicit = ActOnOpenMPMapClause(
3217 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
3218 SourceLocation(), SourceLocation(), ImplicitMaps,
3219 SourceLocation(), SourceLocation(), SourceLocation())) {
3220 ClausesWithImplicit.emplace_back(Implicit);
3221 ErrorFound |=
3222 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3223 } else {
3224 ErrorFound = true;
3225 }
3226 }
3227 }
3228
3229 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3230 switch (Kind) {
3231 case OMPD_parallel:
3232 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3233 EndLoc);
3234 AllowedNameModifiers.push_back(OMPD_parallel);
3235 break;
3236 case OMPD_simd:
3237 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3238 VarsWithInheritedDSA);
3239 break;
3240 case OMPD_for:
3241 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3242 VarsWithInheritedDSA);
3243 break;
3244 case OMPD_for_simd:
3245 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3246 EndLoc, VarsWithInheritedDSA);
3247 break;
3248 case OMPD_sections:
3249 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3250 EndLoc);
3251 break;
3252 case OMPD_section:
3253 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3254, __PRETTY_FUNCTION__))
3254 "No clauses are allowed for 'omp section' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp section' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp section' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3254, __PRETTY_FUNCTION__))
;
3255 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3256 break;
3257 case OMPD_single:
3258 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3259 EndLoc);
3260 break;
3261 case OMPD_master:
3262 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3263, __PRETTY_FUNCTION__))
3263 "No clauses are allowed for 'omp master' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp master' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp master' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3263, __PRETTY_FUNCTION__))
;
3264 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3265 break;
3266 case OMPD_critical:
3267 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3268 StartLoc, EndLoc);
3269 break;
3270 case OMPD_parallel_for:
3271 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3272 EndLoc, VarsWithInheritedDSA);
3273 AllowedNameModifiers.push_back(OMPD_parallel);
3274 break;
3275 case OMPD_parallel_for_simd:
3276 Res = ActOnOpenMPParallelForSimdDirective(
3277 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3278 AllowedNameModifiers.push_back(OMPD_parallel);
3279 break;
3280 case OMPD_parallel_sections:
3281 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3282 StartLoc, EndLoc);
3283 AllowedNameModifiers.push_back(OMPD_parallel);
3284 break;
3285 case OMPD_task:
3286 Res =
3287 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3288 AllowedNameModifiers.push_back(OMPD_task);
3289 break;
3290 case OMPD_taskyield:
3291 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3292, __PRETTY_FUNCTION__))
3292 "No clauses are allowed for 'omp taskyield' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3292, __PRETTY_FUNCTION__))
;
3293 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3294, __PRETTY_FUNCTION__))
3294 "No associated statement allowed for 'omp taskyield' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskyield' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskyield' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3294, __PRETTY_FUNCTION__))
;
3295 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3296 break;
3297 case OMPD_barrier:
3298 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3299, __PRETTY_FUNCTION__))
3299 "No clauses are allowed for 'omp barrier' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3299, __PRETTY_FUNCTION__))
;
3300 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3301, __PRETTY_FUNCTION__))
3301 "No associated statement allowed for 'omp barrier' directive")((AStmt == nullptr && "No associated statement allowed for 'omp barrier' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp barrier' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3301, __PRETTY_FUNCTION__))
;
3302 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3303 break;
3304 case OMPD_taskwait:
3305 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3306, __PRETTY_FUNCTION__))
3306 "No clauses are allowed for 'omp taskwait' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3306, __PRETTY_FUNCTION__))
;
3307 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3308, __PRETTY_FUNCTION__))
3308 "No associated statement allowed for 'omp taskwait' directive")((AStmt == nullptr && "No associated statement allowed for 'omp taskwait' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp taskwait' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3308, __PRETTY_FUNCTION__))
;
3309 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3310 break;
3311 case OMPD_taskgroup:
3312 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3313 EndLoc);
3314 break;
3315 case OMPD_flush:
3316 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3317, __PRETTY_FUNCTION__))
3317 "No associated statement allowed for 'omp flush' directive")((AStmt == nullptr && "No associated statement allowed for 'omp flush' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp flush' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3317, __PRETTY_FUNCTION__))
;
3318 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3319 break;
3320 case OMPD_ordered:
3321 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3322 EndLoc);
3323 break;
3324 case OMPD_atomic:
3325 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3326 EndLoc);
3327 break;
3328 case OMPD_teams:
3329 Res =
3330 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3331 break;
3332 case OMPD_target:
3333 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3334 EndLoc);
3335 AllowedNameModifiers.push_back(OMPD_target);
3336 break;
3337 case OMPD_target_parallel:
3338 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3339 StartLoc, EndLoc);
3340 AllowedNameModifiers.push_back(OMPD_target);
3341 AllowedNameModifiers.push_back(OMPD_parallel);
3342 break;
3343 case OMPD_target_parallel_for:
3344 Res = ActOnOpenMPTargetParallelForDirective(
3345 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3346 AllowedNameModifiers.push_back(OMPD_target);
3347 AllowedNameModifiers.push_back(OMPD_parallel);
3348 break;
3349 case OMPD_cancellation_point:
3350 assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3351, __PRETTY_FUNCTION__))
3351 "No clauses are allowed for 'omp cancellation point' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp cancellation point' directive"
) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3351, __PRETTY_FUNCTION__))
;
3352 assert(AStmt == nullptr && "No associated statement allowed for 'omp "((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3353, __PRETTY_FUNCTION__))
3353 "cancellation point' directive")((AStmt == nullptr && "No associated statement allowed for 'omp "
"cancellation point' directive") ? static_cast<void> (
0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp \" \"cancellation point' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3353, __PRETTY_FUNCTION__))
;
3354 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3355 break;
3356 case OMPD_cancel:
3357 assert(AStmt == nullptr &&((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3358, __PRETTY_FUNCTION__))
3358 "No associated statement allowed for 'omp cancel' directive")((AStmt == nullptr && "No associated statement allowed for 'omp cancel' directive"
) ? static_cast<void> (0) : __assert_fail ("AStmt == nullptr && \"No associated statement allowed for 'omp cancel' directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3358, __PRETTY_FUNCTION__))
;
3359 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3360 CancelRegion);
3361 AllowedNameModifiers.push_back(OMPD_cancel);
3362 break;
3363 case OMPD_target_data:
3364 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3365 EndLoc);
3366 AllowedNameModifiers.push_back(OMPD_target_data);
3367 break;
3368 case OMPD_target_enter_data:
3369 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3370 EndLoc, AStmt);
3371 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3372 break;
3373 case OMPD_target_exit_data:
3374 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3375 EndLoc, AStmt);
3376 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3377 break;
3378 case OMPD_taskloop:
3379 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3380 EndLoc, VarsWithInheritedDSA);
3381 AllowedNameModifiers.push_back(OMPD_taskloop);
3382 break;
3383 case OMPD_taskloop_simd:
3384 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3385 EndLoc, VarsWithInheritedDSA);
3386 AllowedNameModifiers.push_back(OMPD_taskloop);
3387 break;
3388 case OMPD_distribute:
3389 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3390 EndLoc, VarsWithInheritedDSA);
3391 break;
3392 case OMPD_target_update:
3393 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3394 EndLoc, AStmt);
3395 AllowedNameModifiers.push_back(OMPD_target_update);
3396 break;
3397 case OMPD_distribute_parallel_for:
3398 Res = ActOnOpenMPDistributeParallelForDirective(
3399 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3400 AllowedNameModifiers.push_back(OMPD_parallel);
3401 break;
3402 case OMPD_distribute_parallel_for_simd:
3403 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3405 AllowedNameModifiers.push_back(OMPD_parallel);
3406 break;
3407 case OMPD_distribute_simd:
3408 Res = ActOnOpenMPDistributeSimdDirective(
3409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3410 break;
3411 case OMPD_target_parallel_for_simd:
3412 Res = ActOnOpenMPTargetParallelForSimdDirective(
3413 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3414 AllowedNameModifiers.push_back(OMPD_target);
3415 AllowedNameModifiers.push_back(OMPD_parallel);
3416 break;
3417 case OMPD_target_simd:
3418 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3419 EndLoc, VarsWithInheritedDSA);
3420 AllowedNameModifiers.push_back(OMPD_target);
3421 break;
3422 case OMPD_teams_distribute:
3423 Res = ActOnOpenMPTeamsDistributeDirective(
3424 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3425 break;
3426 case OMPD_teams_distribute_simd:
3427 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3428 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3429 break;
3430 case OMPD_teams_distribute_parallel_for_simd:
3431 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3432 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3433 AllowedNameModifiers.push_back(OMPD_parallel);
3434 break;
3435 case OMPD_teams_distribute_parallel_for:
3436 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3437 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3438 AllowedNameModifiers.push_back(OMPD_parallel);
3439 break;
3440 case OMPD_target_teams:
3441 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3442 EndLoc);
3443 AllowedNameModifiers.push_back(OMPD_target);
3444 break;
3445 case OMPD_target_teams_distribute:
3446 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3447 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3448 AllowedNameModifiers.push_back(OMPD_target);
3449 break;
3450 case OMPD_target_teams_distribute_parallel_for:
3451 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3452 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3453 AllowedNameModifiers.push_back(OMPD_target);
3454 AllowedNameModifiers.push_back(OMPD_parallel);
3455 break;
3456 case OMPD_target_teams_distribute_parallel_for_simd:
3457 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3458 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3459 AllowedNameModifiers.push_back(OMPD_target);
3460 AllowedNameModifiers.push_back(OMPD_parallel);
3461 break;
3462 case OMPD_target_teams_distribute_simd:
3463 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3464 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3465 AllowedNameModifiers.push_back(OMPD_target);
3466 break;
3467 case OMPD_declare_target:
3468 case OMPD_end_declare_target:
3469 case OMPD_threadprivate:
3470 case OMPD_declare_reduction:
3471 case OMPD_declare_simd:
3472 case OMPD_requires:
3473 llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3473)
;
3474 case OMPD_unknown:
3475 llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive",
"/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3475)
;
3476 }
3477
3478 for (const auto &P : VarsWithInheritedDSA) {
3479 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3480 << P.first << P.second->getSourceRange();
3481 }
3482 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3483
3484 if (!AllowedNameModifiers.empty())
3485 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3486 ErrorFound;
3487
3488 if (ErrorFound)
3489 return StmtError();
3490 return Res;
3491}
3492
3493Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3494 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3495 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3496 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3497 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3498 assert(Aligneds.size() == Alignments.size())((Aligneds.size() == Alignments.size()) ? static_cast<void
> (0) : __assert_fail ("Aligneds.size() == Alignments.size()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3498, __PRETTY_FUNCTION__))
;
3499 assert(Linears.size() == LinModifiers.size())((Linears.size() == LinModifiers.size()) ? static_cast<void
> (0) : __assert_fail ("Linears.size() == LinModifiers.size()"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3499, __PRETTY_FUNCTION__))
;
3500 assert(Linears.size() == Steps.size())((Linears.size() == Steps.size()) ? static_cast<void> (
0) : __assert_fail ("Linears.size() == Steps.size()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3500, __PRETTY_FUNCTION__))
;
3501 if (!DG || DG.get().isNull())
3502 return DeclGroupPtrTy();
3503
3504 if (!DG.get().isSingleDecl()) {
3505 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3506 return DG;
3507 }
3508 Decl *ADecl = DG.get().getSingleDecl();
3509 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3510 ADecl = FTD->getTemplatedDecl();
3511
3512 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3513 if (!FD) {
3514 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3515 return DeclGroupPtrTy();
3516 }
3517
3518 // OpenMP [2.8.2, declare simd construct, Description]
3519 // The parameter of the simdlen clause must be a constant positive integer
3520 // expression.
3521 ExprResult SL;
3522 if (Simdlen)
3523 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3524 // OpenMP [2.8.2, declare simd construct, Description]
3525 // The special this pointer can be used as if was one of the arguments to the
3526 // function in any of the linear, aligned, or uniform clauses.
3527 // The uniform clause declares one or more arguments to have an invariant
3528 // value for all concurrent invocations of the function in the execution of a
3529 // single SIMD loop.
3530 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3531 const Expr *UniformedLinearThis = nullptr;
3532 for (const Expr *E : Uniforms) {
3533 E = E->IgnoreParenImpCasts();
3534 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3535 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3536 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3537 FD->getParamDecl(PVD->getFunctionScopeIndex())
3538 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3539 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3540 continue;
3541 }
3542 if (isa<CXXThisExpr>(E)) {
3543 UniformedLinearThis = E;
3544 continue;
3545 }
3546 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3547 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3548 }
3549 // OpenMP [2.8.2, declare simd construct, Description]
3550 // The aligned clause declares that the object to which each list item points
3551 // is aligned to the number of bytes expressed in the optional parameter of
3552 // the aligned clause.
3553 // The special this pointer can be used as if was one of the arguments to the
3554 // function in any of the linear, aligned, or uniform clauses.
3555 // The type of list items appearing in the aligned clause must be array,
3556 // pointer, reference to array, or reference to pointer.
3557 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3558 const Expr *AlignedThis = nullptr;
3559 for (const Expr *E : Aligneds) {
3560 E = E->IgnoreParenImpCasts();
3561 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3562 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3563 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3564 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3565 FD->getParamDecl(PVD->getFunctionScopeIndex())
3566 ->getCanonicalDecl() == CanonPVD) {
3567 // OpenMP [2.8.1, simd construct, Restrictions]
3568 // A list-item cannot appear in more than one aligned clause.
3569 if (AlignedArgs.count(CanonPVD) > 0) {
3570 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3571 << 1 << E->getSourceRange();
3572 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3573 diag::note_omp_explicit_dsa)
3574 << getOpenMPClauseName(OMPC_aligned);
3575 continue;
3576 }
3577 AlignedArgs[CanonPVD] = E;
3578 QualType QTy = PVD->getType()
3579 .getNonReferenceType()
3580 .getUnqualifiedType()
3581 .getCanonicalType();
3582 const Type *Ty = QTy.getTypePtrOrNull();
3583 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3584 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3585 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3586 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3587 }
3588 continue;
3589 }
3590 }
3591 if (isa<CXXThisExpr>(E)) {
3592 if (AlignedThis) {
3593 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3594 << 2 << E->getSourceRange();
3595 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3596 << getOpenMPClauseName(OMPC_aligned);
3597 }
3598 AlignedThis = E;
3599 continue;
3600 }
3601 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3602 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3603 }
3604 // The optional parameter of the aligned clause, alignment, must be a constant
3605 // positive integer expression. If no optional parameter is specified,
3606 // implementation-defined default alignments for SIMD instructions on the
3607 // target platforms are assumed.
3608 SmallVector<const Expr *, 4> NewAligns;
3609 for (Expr *E : Alignments) {
3610 ExprResult Align;
3611 if (E)
3612 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3613 NewAligns.push_back(Align.get());
3614 }
3615 // OpenMP [2.8.2, declare simd construct, Description]
3616 // The linear clause declares one or more list items to be private to a SIMD
3617 // lane and to have a linear relationship with respect to the iteration space
3618 // of a loop.
3619 // The special this pointer can be used as if was one of the arguments to the
3620 // function in any of the linear, aligned, or uniform clauses.
3621 // When a linear-step expression is specified in a linear clause it must be
3622 // either a constant integer expression or an integer-typed parameter that is
3623 // specified in a uniform clause on the directive.
3624 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3625 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3626 auto MI = LinModifiers.begin();
3627 for (const Expr *E : Linears) {
3628 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3629 ++MI;
3630 E = E->IgnoreParenImpCasts();
3631 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3632 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3633 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3634 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3635 FD->getParamDecl(PVD->getFunctionScopeIndex())
3636 ->getCanonicalDecl() == CanonPVD) {
3637 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3638 // A list-item cannot appear in more than one linear clause.
3639 if (LinearArgs.count(CanonPVD) > 0) {
3640 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3641 << getOpenMPClauseName(OMPC_linear)
3642 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3643 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3644 diag::note_omp_explicit_dsa)
3645 << getOpenMPClauseName(OMPC_linear);
3646 continue;
3647 }
3648 // Each argument can appear in at most one uniform or linear clause.
3649 if (UniformedArgs.count(CanonPVD) > 0) {
3650 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3651 << getOpenMPClauseName(OMPC_linear)
3652 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3653 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3654 diag::note_omp_explicit_dsa)
3655 << getOpenMPClauseName(OMPC_uniform);
3656 continue;
3657 }
3658 LinearArgs[CanonPVD] = E;
3659 if (E->isValueDependent() || E->isTypeDependent() ||
3660 E->isInstantiationDependent() ||
3661 E->containsUnexpandedParameterPack())
3662 continue;
3663 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3664 PVD->getOriginalType());
3665 continue;
3666 }
3667 }
3668 if (isa<CXXThisExpr>(E)) {
3669 if (UniformedLinearThis) {
3670 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3671 << getOpenMPClauseName(OMPC_linear)
3672 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3673 << E->getSourceRange();
3674 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3675 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3676 : OMPC_linear);
3677 continue;
3678 }
3679 UniformedLinearThis = E;
3680 if (E->isValueDependent() || E->isTypeDependent() ||
3681 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3682 continue;
3683 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3684 E->getType());
3685 continue;
3686 }
3687 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3688 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3689 }
3690 Expr *Step = nullptr;
3691 Expr *NewStep = nullptr;
3692 SmallVector<Expr *, 4> NewSteps;
3693 for (Expr *E : Steps) {
3694 // Skip the same step expression, it was checked already.
3695 if (Step == E || !E) {
3696 NewSteps.push_back(E ? NewStep : nullptr);
3697 continue;
3698 }
3699 Step = E;
3700 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3701 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3702 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3703 if (UniformedArgs.count(CanonPVD) == 0) {
3704 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3705 << Step->getSourceRange();
3706 } else if (E->isValueDependent() || E->isTypeDependent() ||
3707 E->isInstantiationDependent() ||
3708 E->containsUnexpandedParameterPack() ||
3709 CanonPVD->getType()->hasIntegerRepresentation()) {
3710 NewSteps.push_back(Step);
3711 } else {
3712 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3713 << Step->getSourceRange();
3714 }
3715 continue;
3716 }
3717 NewStep = Step;
3718 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3719 !Step->isInstantiationDependent() &&
3720 !Step->containsUnexpandedParameterPack()) {
3721 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3722 .get();
3723 if (NewStep)
3724 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3725 }
3726 NewSteps.push_back(NewStep);
3727 }
3728 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3729 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3730 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3731 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3732 const_cast<Expr **>(Linears.data()), Linears.size(),
3733 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3734 NewSteps.data(), NewSteps.size(), SR);
3735 ADecl->addAttr(NewAttr);
3736 return ConvertDeclToDeclGroup(ADecl);
3737}
3738
3739StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3740 Stmt *AStmt,
3741 SourceLocation StartLoc,
3742 SourceLocation EndLoc) {
3743 if (!AStmt)
3744 return StmtError();
3745
3746 auto *CS = cast<CapturedStmt>(AStmt);
3747 // 1.2.2 OpenMP Language Terminology
3748 // Structured block - An executable statement with a single entry at the
3749 // top and a single exit at the bottom.
3750 // The point of exit cannot be a branch out of the structured block.
3751 // longjmp() and throw() must not violate the entry/exit criteria.
3752 CS->getCapturedDecl()->setNothrow();
3753
3754 setFunctionHasBranchProtectedScope();
3755
3756 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3757 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
3758}
3759
3760namespace {
3761/// Helper class for checking canonical form of the OpenMP loops and
3762/// extracting iteration space of each loop in the loop nest, that will be used
3763/// for IR generation.
3764class OpenMPIterationSpaceChecker {
3765 /// Reference to Sema.
3766 Sema &SemaRef;
3767 /// A location for diagnostics (when there is no some better location).
3768 SourceLocation DefaultLoc;
3769 /// A location for diagnostics (when increment is not compatible).
3770 SourceLocation ConditionLoc;
3771 /// A source location for referring to loop init later.
3772 SourceRange InitSrcRange;
3773 /// A source location for referring to condition later.
3774 SourceRange ConditionSrcRange;
3775 /// A source location for referring to increment later.
3776 SourceRange IncrementSrcRange;
3777 /// Loop variable.
3778 ValueDecl *LCDecl = nullptr;
3779 /// Reference to loop variable.
3780 Expr *LCRef = nullptr;
3781 /// Lower bound (initializer for the var).
3782 Expr *LB = nullptr;
3783 /// Upper bound.
3784 Expr *UB = nullptr;
3785 /// Loop step (increment).
3786 Expr *Step = nullptr;
3787 /// This flag is true when condition is one of:
3788 /// Var < UB
3789 /// Var <= UB
3790 /// UB > Var
3791 /// UB >= Var
3792 bool TestIsLessOp = false;
3793 /// This flag is true when condition is strict ( < or > ).
3794 bool TestIsStrictOp = false;
3795 /// This flag is true when step is subtracted on each iteration.
3796 bool SubtractStep = false;
3797
3798public:
3799 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3800 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3801 /// Check init-expr for canonical loop form and save loop counter
3802 /// variable - #Var and its initialization value - #LB.
3803 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
3804 /// Check test-expr for canonical form, save upper-bound (#UB), flags
3805 /// for less/greater and for strict/non-strict comparison.
3806 bool checkAndSetCond(Expr *S);
3807 /// Check incr-expr for canonical loop form and return true if it
3808 /// does not conform, otherwise save loop step (#Step).
3809 bool checkAndSetInc(Expr *S);
3810 /// Return the loop counter variable.
3811 ValueDecl *getLoopDecl() const { return LCDecl; }
3812 /// Return the reference expression to loop counter variable.
3813 Expr *getLoopDeclRefExpr() const { return LCRef; }
3814 /// Source range of the loop init.
3815 SourceRange getInitSrcRange() const { return InitSrcRange; }
3816 /// Source range of the loop condition.
3817 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
3818 /// Source range of the loop increment.
3819 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
3820 /// True if the step should be subtracted.
3821 bool shouldSubtractStep() const { return SubtractStep; }
3822 /// Build the expression to calculate the number of iterations.
3823 Expr *buildNumIterations(
3824 Scope *S, const bool LimitedType,
3825 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3826 /// Build the precondition expression for the loops.
3827 Expr *
3828 buildPreCond(Scope *S, Expr *Cond,
3829 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3830 /// Build reference expression to the counter be used for codegen.
3831 DeclRefExpr *
3832 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3833 DSAStackTy &DSA) const;
3834 /// Build reference expression to the private counter be used for
3835 /// codegen.
3836 Expr *buildPrivateCounterVar() const;
3837 /// Build initialization of the counter be used for codegen.
3838 Expr *buildCounterInit() const;
3839 /// Build step of the counter be used for codegen.
3840 Expr *buildCounterStep() const;
3841 /// Build loop data with counter value for depend clauses in ordered
3842 /// directives.
3843 Expr *
3844 buildOrderedLoopData(Scope *S, Expr *Counter,
3845 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3846 SourceLocation Loc, Expr *Inc = nullptr,
3847 OverloadedOperatorKind OOK = OO_Amp);
3848 /// Return true if any expression is dependent.
3849 bool dependent() const;
3850
3851private:
3852 /// Check the right-hand side of an assignment in the increment
3853 /// expression.
3854 bool checkAndSetIncRHS(Expr *RHS);
3855 /// Helper to set loop counter variable and its initializer.
3856 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3857 /// Helper to set upper bound.
3858 bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3859 SourceLocation SL);
3860 /// Helper to set loop increment.
3861 bool setStep(Expr *NewStep, bool Subtract);
3862};
3863
3864bool OpenMPIterationSpaceChecker::dependent() const {
3865 if (!LCDecl) {
3866 assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void>
(0) : __assert_fail ("!LB && !UB && !Step", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3866, __PRETTY_FUNCTION__))
;
3867 return false;
3868 }
3869 return LCDecl->getType()->isDependentType() ||
3870 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3871 (Step && Step->isValueDependent());
3872}
3873
3874bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
3875 Expr *NewLCRefExpr,
3876 Expr *NewLB) {
3877 // State consistency checking to ensure correct usage.
3878 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3879, __PRETTY_FUNCTION__))
3879 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl == nullptr && LB == nullptr && LCRef
== nullptr && UB == nullptr && Step == nullptr
&& !TestIsLessOp && !TestIsStrictOp) ? static_cast
<void> (0) : __assert_fail ("LCDecl == nullptr && LB == nullptr && LCRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3879, __PRETTY_FUNCTION__))
;
3880 if (!NewLCDecl || !NewLB)
3881 return true;
3882 LCDecl = getCanonicalDecl(NewLCDecl);
3883 LCRef = NewLCRefExpr;
3884 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3885 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3886 if ((Ctor->isCopyOrMoveConstructor() ||
3887 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3888 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3889 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3890 LB = NewLB;
3891 return false;
3892}
3893
3894bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp,
3895 SourceRange SR, SourceLocation SL) {
3896 // State consistency checking to ensure correct usage.
3897 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3898, __PRETTY_FUNCTION__))
3898 Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((LCDecl != nullptr && LB != nullptr && UB ==
nullptr && Step == nullptr && !TestIsLessOp &&
!TestIsStrictOp) ? static_cast<void> (0) : __assert_fail
("LCDecl != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3898, __PRETTY_FUNCTION__))
;
3899 if (!NewUB)
3900 return true;
3901 UB = NewUB;
3902 TestIsLessOp = LessOp;
3903 TestIsStrictOp = StrictOp;
3904 ConditionSrcRange = SR;
3905 ConditionLoc = SL;
3906 return false;
3907}
3908
3909bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
3910 // State consistency checking to ensure correct usage.
3911 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr)((LCDecl != nullptr && LB != nullptr && Step ==
nullptr) ? static_cast<void> (0) : __assert_fail ("LCDecl != nullptr && LB != nullptr && Step == nullptr"
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 3911, __PRETTY_FUNCTION__))
;
3912 if (!NewStep)
3913 return true;
3914 if (!NewStep->isValueDependent()) {
3915 // Check that the step is integer expression.
3916 SourceLocation StepLoc = NewStep->getBeginLoc();
3917 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3918 StepLoc, getExprAsWritten(NewStep));
3919 if (Val.isInvalid())
3920 return true;
3921 NewStep = Val.get();
3922
3923 // OpenMP [2.6, Canonical Loop Form, Restrictions]
3924 // If test-expr is of form var relational-op b and relational-op is < or
3925 // <= then incr-expr must cause var to increase on each iteration of the
3926 // loop. If test-expr is of form var relational-op b and relational-op is
3927 // > or >= then incr-expr must cause var to decrease on each iteration of
3928 // the loop.
3929 // If test-expr is of form b relational-op var and relational-op is < or
3930 // <= then incr-expr must cause var to decrease on each iteration of the
3931 // loop. If test-expr is of form b relational-op var and relational-op is
3932 // > or >= then incr-expr must cause var to increase on each iteration of
3933 // the loop.
3934 llvm::APSInt Result;
3935 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3936 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3937 bool IsConstNeg =
3938 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3939 bool IsConstPos =
3940 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3941 bool IsConstZero = IsConstant && !Result.getBoolValue();
3942 if (UB && (IsConstZero ||
3943 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3944 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3945 SemaRef.Diag(NewStep->getExprLoc(),
3946 diag::err_omp_loop_incr_not_compatible)
3947 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3948 SemaRef.Diag(ConditionLoc,
3949 diag::note_omp_loop_cond_requres_compatible_incr)
3950 << TestIsLessOp << ConditionSrcRange;
3951 return true;
3952 }
3953 if (TestIsLessOp == Subtract) {
3954 NewStep =
3955 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3956 .get();
3957 Subtract = !Subtract;
3958 }
3959 }
3960
3961 Step = NewStep;
3962 SubtractStep = Subtract;
3963 return false;
3964}
3965
3966bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
3967 // Check init-expr for canonical loop form and save loop counter
3968 // variable - #Var and its initialization value - #LB.
3969 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3970 // var = lb
3971 // integer-type var = lb
3972 // random-access-iterator-type var = lb
3973 // pointer-type var = lb
3974 //
3975 if (!S) {
3976 if (EmitDiags) {
3977 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3978 }
3979 return true;
3980 }
3981 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3982 if (!ExprTemp->cleanupsHaveSideEffects())
3983 S = ExprTemp->getSubExpr();
3984
3985 InitSrcRange = S->getSourceRange();
3986 if (Expr *E = dyn_cast<Expr>(S))
3987 S = E->IgnoreParens();
3988 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3989 if (BO->getOpcode() == BO_Assign) {
3990 Expr *LHS = BO->getLHS()->IgnoreParens();
3991 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3992 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3993 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3994 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3995 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3996 }
3997 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3998 if (ME->isArrow() &&
3999 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4000 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4001 }
4002 }
4003 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
4004 if (DS->isSingleDecl()) {
4005 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4006 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4007 // Accept non-canonical init form here but emit ext. warning.
4008 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
4009 SemaRef.Diag(S->getBeginLoc(),
4010 diag::ext_omp_loop_not_canonical_init)
4011 << S->getSourceRange();
4012 return setLCDeclAndLB(
4013 Var,
4014 buildDeclRefExpr(SemaRef, Var,
4015 Var->getType().getNonReferenceType(),
4016 DS->getBeginLoc()),
4017 Var->getInit());
4018 }
4019 }
4020 }
4021 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4022 if (CE->getOperator() == OO_Equal) {
4023 Expr *LHS = CE->getArg(0);
4024 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4025 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4026 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4027 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4028 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4029 }
4030 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4031 if (ME->isArrow() &&
4032 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4033 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4034 }
4035 }
4036 }
4037
4038 if (dependent() || SemaRef.CurContext->isDependentContext())
4039 return false;
4040 if (EmitDiags) {
4041 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
4042 << S->getSourceRange();
4043 }
4044 return true;
4045}
4046
4047/// Ignore parenthesizes, implicit casts, copy constructor and return the
4048/// variable (which may be the loop variable) if possible.
4049static const ValueDecl *getInitLCDecl(const Expr *E) {
4050 if (!E)
4051 return nullptr;
4052 E = getExprAsWritten(E);
4053 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4054 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4055 if ((Ctor->isCopyOrMoveConstructor() ||
4056 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4057 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4058 E = CE->getArg(0)->IgnoreParenImpCasts();
4059 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4060 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4061 return getCanonicalDecl(VD);
4062 }
4063 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
4064 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4065 return getCanonicalDecl(ME->getMemberDecl());
4066 return nullptr;
4067}
4068
4069bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
4070 // Check test-expr for canonical form, save upper-bound UB, flags for
4071 // less/greater and for strict/non-strict comparison.
4072 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4073 // var relational-op b
4074 // b relational-op var
4075 //
4076 if (!S) {
4077 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4078 return true;
4079 }
4080 S = getExprAsWritten(S);
4081 SourceLocation CondLoc = S->getBeginLoc();
4082 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4083 if (BO->isRelationalOp()) {
4084 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4085 return setUB(BO->getRHS(),
4086 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4087 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4088 BO->getSourceRange(), BO->getOperatorLoc());
4089 if (getInitLCDecl(BO->getRHS()) == LCDecl)
4090 return setUB(BO->getLHS(),
4091 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4092 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4093 BO->getSourceRange(), BO->getOperatorLoc());
4094 }
4095 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4096 if (CE->getNumArgs() == 2) {
4097 auto Op = CE->getOperator();
4098 switch (Op) {
4099 case OO_Greater:
4100 case OO_GreaterEqual:
4101 case OO_Less:
4102 case OO_LessEqual:
4103 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4104 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4105 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4106 CE->getOperatorLoc());
4107 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4108 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4109 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4110 CE->getOperatorLoc());
4111 break;
4112 default:
4113 break;
4114 }
4115 }
4116 }
4117 if (dependent() || SemaRef.CurContext->isDependentContext())
4118 return false;
4119 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4120 << S->getSourceRange() << LCDecl;
4121 return true;
4122}
4123
4124bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4125 // RHS of canonical loop form increment can be:
4126 // var + incr
4127 // incr + var
4128 // var - incr
4129 //
4130 RHS = RHS->IgnoreParenImpCasts();
4131 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4132 if (BO->isAdditiveOp()) {
4133 bool IsAdd = BO->getOpcode() == BO_Add;
4134 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4135 return setStep(BO->getRHS(), !IsAdd);
4136 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4137 return setStep(BO->getLHS(), /*Subtract=*/false);
4138 }
4139 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4140 bool IsAdd = CE->getOperator() == OO_Plus;
4141 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4142 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4143 return setStep(CE->getArg(1), !IsAdd);
4144 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4145 return setStep(CE->getArg(0), /*Subtract=*/false);
4146 }
4147 }
4148 if (dependent() || SemaRef.CurContext->isDependentContext())
4149 return false;
4150 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4151 << RHS->getSourceRange() << LCDecl;
4152 return true;
4153}
4154
4155bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4156 // Check incr-expr for canonical loop form and return true if it
4157 // does not conform.
4158 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4159 // ++var
4160 // var++
4161 // --var
4162 // var--
4163 // var += incr
4164 // var -= incr
4165 // var = var + incr
4166 // var = incr + var
4167 // var = var - incr
4168 //
4169 if (!S) {
4170 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4171 return true;
4172 }
4173 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4174 if (!ExprTemp->cleanupsHaveSideEffects())
4175 S = ExprTemp->getSubExpr();
4176
4177 IncrementSrcRange = S->getSourceRange();
4178 S = S->IgnoreParens();
4179 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4180 if (UO->isIncrementDecrementOp() &&
4181 getInitLCDecl(UO->getSubExpr()) == LCDecl)
4182 return setStep(SemaRef
4183 .ActOnIntegerConstant(UO->getBeginLoc(),
4184 (UO->isDecrementOp() ? -1 : 1))
4185 .get(),
4186 /*Subtract=*/false);
4187 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4188 switch (BO->getOpcode()) {
4189 case BO_AddAssign:
4190 case BO_SubAssign:
4191 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4192 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4193 break;
4194 case BO_Assign:
4195 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4196 return checkAndSetIncRHS(BO->getRHS());
4197 break;
4198 default:
4199 break;
4200 }
4201 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4202 switch (CE->getOperator()) {
4203 case OO_PlusPlus:
4204 case OO_MinusMinus:
4205 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4206 return setStep(SemaRef
4207 .ActOnIntegerConstant(
4208 CE->getBeginLoc(),
4209 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4210 .get(),
4211 /*Subtract=*/false);
4212 break;
4213 case OO_PlusEqual:
4214 case OO_MinusEqual:
4215 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4216 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4217 break;
4218 case OO_Equal:
4219 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4220 return checkAndSetIncRHS(CE->getArg(1));
4221 break;
4222 default:
4223 break;
4224 }
4225 }
4226 if (dependent() || SemaRef.CurContext->isDependentContext())
4227 return false;
4228 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4229 << S->getSourceRange() << LCDecl;
4230 return true;
4231}
4232
4233static ExprResult
4234tryBuildCapture(Sema &SemaRef, Expr *Capture,
4235 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4236 if (SemaRef.CurContext->isDependentContext())
4237 return ExprResult(Capture);
4238 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4239 return SemaRef.PerformImplicitConversion(
4240 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4241 /*AllowExplicit=*/true);
4242 auto I = Captures.find(Capture);
4243 if (I != Captures.end())
4244 return buildCapture(SemaRef, Capture, I->second);
4245 DeclRefExpr *Ref = nullptr;
4246 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4247 Captures[Capture] = Ref;
4248 return Res;
4249}
4250
4251/// Build the expression to calculate the number of iterations.
4252Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4253 Scope *S, const bool LimitedType,
4254 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4255 ExprResult Diff;
4256 QualType VarType = LCDecl->getType().getNonReferenceType();
4257 if (VarType->isIntegerType() || VarType->isPointerType() ||
4258 SemaRef.getLangOpts().CPlusPlus) {
4259 // Upper - Lower
4260 Expr *UBExpr = TestIsLessOp ? UB : LB;
4261 Expr *LBExpr = TestIsLessOp ? LB : UB;
4262 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4263 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4264 if (!Upper || !Lower)
4265 return nullptr;
4266
4267 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4268
4269 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4270 // BuildBinOp already emitted error, this one is to point user to upper
4271 // and lower bound, and to tell what is passed to 'operator-'.
4272 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4273 << Upper->getSourceRange() << Lower->getSourceRange();
4274 return nullptr;
4275 }
4276 }
4277
4278 if (!Diff.isUsable())
4279 return nullptr;
4280
4281 // Upper - Lower [- 1]
4282 if (TestIsStrictOp)
4283 Diff = SemaRef.BuildBinOp(
4284 S, DefaultLoc, BO_Sub, Diff.get(),
4285 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4286 if (!Diff.isUsable())
4287 return nullptr;
4288
4289 // Upper - Lower [- 1] + Step
4290 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4291 if (!NewStep.isUsable())
4292 return nullptr;
4293 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4294 if (!Diff.isUsable())
4295 return nullptr;
4296
4297 // Parentheses (for dumping/debugging purposes only).
4298 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4299 if (!Diff.isUsable())
4300 return nullptr;
4301
4302 // (Upper - Lower [- 1] + Step) / Step
4303 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4304 if (!Diff.isUsable())
4305 return nullptr;
4306
4307 // OpenMP runtime requires 32-bit or 64-bit loop variables.
4308 QualType Type = Diff.get()->getType();
4309 ASTContext &C = SemaRef.Context;
4310 bool UseVarType = VarType->hasIntegerRepresentation() &&
4311 C.getTypeSize(Type) > C.getTypeSize(VarType);
4312 if (!Type->isIntegerType() || UseVarType) {
4313 unsigned NewSize =
4314 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4315 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4316 : Type->hasSignedIntegerRepresentation();
4317 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4318 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4319 Diff = SemaRef.PerformImplicitConversion(
4320 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4321 if (!Diff.isUsable())
4322 return nullptr;
4323 }
4324 }
4325 if (LimitedType) {
4326 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4327 if (NewSize != C.getTypeSize(Type)) {
4328 if (NewSize < C.getTypeSize(Type)) {
4329 assert(NewSize == 64 && "incorrect loop var size")((NewSize == 64 && "incorrect loop var size") ? static_cast
<void> (0) : __assert_fail ("NewSize == 64 && \"incorrect loop var size\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4329, __PRETTY_FUNCTION__))
;
4330 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4331 << InitSrcRange << ConditionSrcRange;
4332 }
4333 QualType NewType = C.getIntTypeForBitwidth(
4334 NewSize, Type->hasSignedIntegerRepresentation() ||
4335 C.getTypeSize(Type) < NewSize);
4336 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4337 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4338 Sema::AA_Converting, true);
4339 if (!Diff.isUsable())
4340 return nullptr;
4341 }
4342 }
4343 }
4344
4345 return Diff.get();
4346}
4347
4348Expr *OpenMPIterationSpaceChecker::buildPreCond(
4349 Scope *S, Expr *Cond,
4350 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4351 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4352 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4353 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4354
4355 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4356 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4357 if (!NewLB.isUsable() || !NewUB.isUsable())
4358 return nullptr;
4359
4360 ExprResult CondExpr =
4361 SemaRef.BuildBinOp(S, DefaultLoc,
4362 TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4363 : (TestIsStrictOp ? BO_GT : BO_GE),
4364 NewLB.get(), NewUB.get());
4365 if (CondExpr.isUsable()) {
4366 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4367 SemaRef.Context.BoolTy))
4368 CondExpr = SemaRef.PerformImplicitConversion(
4369 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4370 /*AllowExplicit=*/true);
4371 }
4372 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4373 // Otherwise use original loop conditon and evaluate it in runtime.
4374 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4375}
4376
4377/// Build reference expression to the counter be used for codegen.
4378DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4379 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4380 DSAStackTy &DSA) const {
4381 auto *VD = dyn_cast<VarDecl>(LCDecl);
4382 if (!VD) {
4383 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4384 DeclRefExpr *Ref = buildDeclRefExpr(
4385 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4386 const DSAStackTy::DSAVarData Data =
4387 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4388 // If the loop control decl is explicitly marked as private, do not mark it
4389 // as captured again.
4390 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4391 Captures.insert(std::make_pair(LCRef, Ref));
4392 return Ref;
4393 }
4394 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4395 DefaultLoc);
4396}
4397
4398Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4399 if (LCDecl && !LCDecl->isInvalidDecl()) {
4400 QualType Type = LCDecl->getType().getNonReferenceType();
4401 VarDecl *PrivateVar = buildVarDecl(
4402 SemaRef, DefaultLoc, Type, LCDecl->getName(),
4403 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4404 isa<VarDecl>(LCDecl)
4405 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4406 : nullptr);
4407 if (PrivateVar->isInvalidDecl())
4408 return nullptr;
4409 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4410 }
4411 return nullptr;
4412}
4413
4414/// Build initialization of the counter to be used for codegen.
4415Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
4416
4417/// Build step of the counter be used for codegen.
4418Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4419
4420Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4421 Scope *S, Expr *Counter,
4422 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
4423 Expr *Inc, OverloadedOperatorKind OOK) {
4424 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4425 if (!Cnt)
4426 return nullptr;
4427 if (Inc) {
4428 assert((OOK == OO_Plus || OOK == OO_Minus) &&(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4429, __PRETTY_FUNCTION__))
4429 "Expected only + or - operations for depend clauses.")(((OOK == OO_Plus || OOK == OO_Minus) && "Expected only + or - operations for depend clauses."
) ? static_cast<void> (0) : __assert_fail ("(OOK == OO_Plus || OOK == OO_Minus) && \"Expected only + or - operations for depend clauses.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4429, __PRETTY_FUNCTION__))
;
4430 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4431 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
4432 if (!Cnt)
4433 return nullptr;
4434 }
4435 ExprResult Diff;
4436 QualType VarType = LCDecl->getType().getNonReferenceType();
4437 if (VarType->isIntegerType() || VarType->isPointerType() ||
4438 SemaRef.getLangOpts().CPlusPlus) {
4439 // Upper - Lower
4440 Expr *Upper =
4441 TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4442 Expr *Lower =
4443 TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4444 if (!Upper || !Lower)
4445 return nullptr;
4446
4447 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4448
4449 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4450 // BuildBinOp already emitted error, this one is to point user to upper
4451 // and lower bound, and to tell what is passed to 'operator-'.
4452 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4453 << Upper->getSourceRange() << Lower->getSourceRange();
4454 return nullptr;
4455 }
4456 }
4457
4458 if (!Diff.isUsable())
4459 return nullptr;
4460
4461 // Parentheses (for dumping/debugging purposes only).
4462 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4463 if (!Diff.isUsable())
4464 return nullptr;
4465
4466 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4467 if (!NewStep.isUsable())
4468 return nullptr;
4469 // (Upper - Lower) / Step
4470 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4471 if (!Diff.isUsable())
4472 return nullptr;
4473
4474 return Diff.get();
4475}
4476
4477/// Iteration space of a single for loop.
4478struct LoopIterationSpace final {
4479 /// Condition of the loop.
4480 Expr *PreCond = nullptr;
4481 /// This expression calculates the number of iterations in the loop.
4482 /// It is always possible to calculate it before starting the loop.
4483 Expr *NumIterations = nullptr;
4484 /// The loop counter variable.
4485 Expr *CounterVar = nullptr;
4486 /// Private loop counter variable.
4487 Expr *PrivateCounterVar = nullptr;
4488 /// This is initializer for the initial value of #CounterVar.
4489 Expr *CounterInit = nullptr;
4490 /// This is step for the #CounterVar used to generate its update:
4491 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4492 Expr *CounterStep = nullptr;
4493 /// Should step be subtracted?
4494 bool Subtract = false;
4495 /// Source range of the loop init.
4496 SourceRange InitSrcRange;
4497 /// Source range of the loop condition.
4498 SourceRange CondSrcRange;
4499 /// Source range of the loop increment.
4500 SourceRange IncSrcRange;
4501};
4502
4503} // namespace
4504
4505void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4506 assert(getLangOpts().OpenMP && "OpenMP is not active.")((getLangOpts().OpenMP && "OpenMP is not active.") ? static_cast
<void> (0) : __assert_fail ("getLangOpts().OpenMP && \"OpenMP is not active.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4506, __PRETTY_FUNCTION__))
;
4507 assert(Init && "Expected loop in canonical form.")((Init && "Expected loop in canonical form.") ? static_cast
<void> (0) : __assert_fail ("Init && \"Expected loop in canonical form.\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4507, __PRETTY_FUNCTION__))
;
4508 unsigned AssociatedLoops = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getAssociatedLoops();
4509 if (AssociatedLoops > 0 &&
4510 isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->getCurrentDirective())) {
4511 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4512 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
4513 if (ValueDecl *D = ISC.getLoopDecl()) {
4514 auto *VD = dyn_cast<VarDecl>(D);
4515 if (!VD) {
4516 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
4517 VD = Private;
4518 } else {
4519 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
4520 /*WithInit=*/false);
4521 VD = cast<VarDecl>(Ref->getDecl());
4522 }
4523 }
4524 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->addLoopControlVariable(D, VD);
4525 }
4526 }
4527 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setAssociatedLoops(AssociatedLoops - 1);
4528 }
4529}
4530
4531/// Called on a for stmt to check and extract its iteration space
4532/// for further processing (such as collapsing).
4533static bool checkOpenMPIterationSpace(
4534 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4535 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4536 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
4537 Expr *OrderedLoopCountExpr,
4538 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4539 LoopIterationSpace &ResultIterSpace,
4540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4541 // OpenMP [2.6, Canonical Loop Form]
4542 // for (init-expr; test-expr; incr-expr) structured-block
4543 auto *For = dyn_cast_or_null<ForStmt>(S);
4544 if (!For) {
4545 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
4546 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4547 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
4548 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4549 if (TotalNestedLoopCount > 1) {
4550 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4551 SemaRef.Diag(DSA.getConstructLoc(),
4552 diag::note_omp_collapse_ordered_expr)
4553 << 2 << CollapseLoopCountExpr->getSourceRange()
4554 << OrderedLoopCountExpr->getSourceRange();
4555 else if (CollapseLoopCountExpr)
4556 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4557 diag::note_omp_collapse_ordered_expr)
4558 << 0 << CollapseLoopCountExpr->getSourceRange();
4559 else
4560 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4561 diag::note_omp_collapse_ordered_expr)
4562 << 1 << OrderedLoopCountExpr->getSourceRange();
4563 }
4564 return true;
4565 }
4566 assert(For->getBody())((For->getBody()) ? static_cast<void> (0) : __assert_fail
("For->getBody()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4566, __PRETTY_FUNCTION__))
;
4567
4568 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4569
4570 // Check init.
4571 Stmt *Init = For->getInit();
4572 if (ISC.checkAndSetInit(Init))
4573 return true;
4574
4575 bool HasErrors = false;
4576
4577 // Check loop variable's type.
4578 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
4579 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4580
4581 // OpenMP [2.6, Canonical Loop Form]
4582 // Var is one of the following:
4583 // A variable of signed or unsigned integer type.
4584 // For C++, a variable of a random access iterator type.
4585 // For C, a variable of a pointer type.
4586 QualType VarType = LCDecl->getType().getNonReferenceType();
4587 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4588 !VarType->isPointerType() &&
4589 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4590 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
4591 << SemaRef.getLangOpts().CPlusPlus;
4592 HasErrors = true;
4593 }
4594
4595 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4596 // a Construct
4597 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4598 // parallel for construct is (are) private.
4599 // The loop iteration variable in the associated for-loop of a simd
4600 // construct with just one associated for-loop is linear with a
4601 // constant-linear-step that is the increment of the associated for-loop.
4602 // Exclude loop var from the list of variables with implicitly defined data
4603 // sharing attributes.
4604 VarsWithImplicitDSA.erase(LCDecl);
4605
4606 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4607 // in a Construct, C/C++].
4608 // The loop iteration variable in the associated for-loop of a simd
4609 // construct with just one associated for-loop may be listed in a linear
4610 // clause with a constant-linear-step that is the increment of the
4611 // associated for-loop.
4612 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4613 // parallel for construct may be listed in a private or lastprivate clause.
4614 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4615 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4616 // declared in the loop and it is predetermined as a private.
4617 OpenMPClauseKind PredeterminedCKind =
4618 isOpenMPSimdDirective(DKind)
4619 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4620 : OMPC_private;
4621 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4622 DVar.CKind != PredeterminedCKind) ||
4623 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4624 isOpenMPDistributeDirective(DKind)) &&
4625 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4626 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4627 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4628 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
4629 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4630 << getOpenMPClauseName(PredeterminedCKind);
4631 if (DVar.RefExpr == nullptr)
4632 DVar.CKind = PredeterminedCKind;
4633 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4634 HasErrors = true;
4635 } else if (LoopDeclRefExpr != nullptr) {
4636 // Make the loop iteration variable private (for worksharing constructs),
4637 // linear (for simd directives with the only one associated loop) or
4638 // lastprivate (for simd directives with several collapsed or ordered
4639 // loops).
4640 if (DVar.CKind == OMPC_unknown)
4641 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4642 [](OpenMPDirectiveKind) -> bool { return true; },
4643 /*FromParent=*/false);
4644 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4645 }
4646
4647 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars")((isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"
) ? static_cast<void> (0) : __assert_fail ("isOpenMPLoopDirective(DKind) && \"DSA for non-loop vars\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 4647, __PRETTY_FUNCTION__))
;
4648
4649 // Check test-expr.
4650 HasErrors |= ISC.checkAndSetCond(For->getCond());
4651
4652 // Check incr-expr.
4653 HasErrors |= ISC.checkAndSetInc(For->getInc());
4654 }
4655
4656 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4657 return HasErrors;
4658
4659 // Build the loop's iteration space representation.
4660 ResultIterSpace.PreCond =
4661 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4662 ResultIterSpace.NumIterations = ISC.buildNumIterations(
4663 DSA.getCurScope(),
4664 (isOpenMPWorksharingDirective(DKind) ||
4665 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4666 Captures);
4667 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4668 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4669 ResultIterSpace.CounterInit = ISC.buildCounterInit();
4670 ResultIterSpace.CounterStep = ISC.buildCounterStep();
4671 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4672 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4673 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4674 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4675
4676 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4677 ResultIterSpace.NumIterations == nullptr ||
4678 ResultIterSpace.CounterVar == nullptr ||
4679 ResultIterSpace.PrivateCounterVar == nullptr ||
4680 ResultIterSpace.CounterInit == nullptr ||
4681 ResultIterSpace.CounterStep == nullptr);
4682 if (!HasErrors && DSA.isOrderedRegion()) {
4683 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4684 if (CurrentNestedLoopCount <
4685 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4686 DSA.getOrderedRegionParam().second->setLoopNumIterations(
4687 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4688 DSA.getOrderedRegionParam().second->setLoopCounter(
4689 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4690 }
4691 }
4692 for (auto &Pair : DSA.getDoacrossDependClauses()) {
4693 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4694 // Erroneous case - clause has some problems.
4695 continue;
4696 }
4697 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4698 Pair.second.size() <= CurrentNestedLoopCount) {
4699 // Erroneous case - clause has some problems.
4700 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
4701 continue;
4702 }
4703 Expr *CntValue;
4704 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4705 CntValue = ISC.buildOrderedLoopData(
4706 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4707 Pair.first->getDependencyLoc());
4708 else
4709 CntValue = ISC.buildOrderedLoopData(
4710 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4711 Pair.first->getDependencyLoc(),
4712 Pair.second[CurrentNestedLoopCount].first,
4713 Pair.second[CurrentNestedLoopCount].second);
4714 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4715 }
4716 }
4717
4718 return HasErrors;
4719}
4720
4721/// Build 'VarRef = Start.
4722static ExprResult
4723buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4724 ExprResult Start,
4725 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4726 // Build 'VarRef = Start.
4727 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4728 if (!NewStart.isUsable())
4729 return ExprError();
4730 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4731 VarRef.get()->getType())) {
4732 NewStart = SemaRef.PerformImplicitConversion(
4733 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4734 /*AllowExplicit=*/true);
4735 if (!NewStart.isUsable())
4736 return ExprError();
4737 }
4738
4739 ExprResult Init =
4740 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4741 return Init;
4742}
4743
4744/// Build 'VarRef = Start + Iter * Step'.
4745static ExprResult buildCounterUpdate(
4746 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4747 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
4748 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
4749 // Add parentheses (for debugging purposes only).
4750 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4751 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4752 !Step.isUsable())
4753 return ExprError();
4754
4755 ExprResult NewStep = Step;
4756 if (Captures)
4757 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4758 if (NewStep.isInvalid())
4759 return ExprError();
4760 ExprResult Update =
4761 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4762 if (!Update.isUsable())
4763 return ExprError();
4764
4765 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4766 // 'VarRef = Start (+|-) Iter * Step'.
4767 ExprResult NewStart = Start;
4768 if (Captures)
4769 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4770 if (NewStart.isInvalid())
4771 return ExprError();
4772
4773 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4774 ExprResult SavedUpdate = Update;
4775 ExprResult UpdateVal;
4776 if (VarRef.get()->getType()->isOverloadableType() ||
4777 NewStart.get()->getType()->isOverloadableType() ||
4778 Update.get()->getType()->isOverloadableType()) {
4779 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4780 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4781 Update =
4782 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4783 if (Update.isUsable()) {
4784 UpdateVal =
4785 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4786 VarRef.get(), SavedUpdate.get());
4787 if (UpdateVal.isUsable()) {
4788 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4789 UpdateVal.get());
4790 }
4791 }
4792 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4793 }
4794
4795 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4796 if (!Update.isUsable() || !UpdateVal.isUsable()) {
4797 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4798 NewStart.get(), SavedUpdate.get());
4799 if (!Update.isUsable())
4800 return ExprError();
4801
4802 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4803 VarRef.get()->getType())) {
4804 Update = SemaRef.PerformImplicitConversion(
4805 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4806 if (!Update.isUsable())
4807 return ExprError();
4808 }
4809
4810 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4811 }
4812 return Update;
4813}
4814
4815/// Convert integer expression \a E to make it have at least \a Bits
4816/// bits.
4817static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4818 if (E == nullptr)
4819 return ExprError();
4820 ASTContext &C = SemaRef.Context;
4821 QualType OldType = E->getType();
4822 unsigned HasBits = C.getTypeSize(OldType);
4823 if (HasBits >= Bits)
4824 return ExprResult(E);
4825 // OK to convert to signed, because new type has more bits than old.
4826 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4827 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4828 true);
4829}
4830
4831/// Check if the given expression \a E is a constant integer that fits
4832/// into \a Bits bits.
4833static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
4834 if (E == nullptr)
4835 return false;
4836 llvm::APSInt Result;
4837 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4838 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4839 return false;
4840}
4841
4842/// Build preinits statement for the given declarations.
4843static Stmt *buildPreInits(ASTContext &Context,
4844 MutableArrayRef<Decl *> PreInits) {
4845 if (!PreInits.empty()) {
4846 return new (Context) DeclStmt(
4847 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4848 SourceLocation(), SourceLocation());
4849 }
4850 return nullptr;
4851}
4852
4853/// Build preinits statement for the given declarations.
4854static Stmt *
4855buildPreInits(ASTContext &Context,
4856 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4857 if (!Captures.empty()) {
4858 SmallVector<Decl *, 16> PreInits;
4859 for (const auto &Pair : Captures)
4860 PreInits.push_back(Pair.second->getDecl());
4861 return buildPreInits(Context, PreInits);
4862 }
4863 return nullptr;
4864}
4865
4866/// Build postupdate expression for the given list of postupdates expressions.
4867static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4868 Expr *PostUpdate = nullptr;
4869 if (!PostUpdates.empty()) {
4870 for (Expr *E : PostUpdates) {
4871 Expr *ConvE = S.BuildCStyleCastExpr(
4872 E->getExprLoc(),
4873 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4874 E->getExprLoc(), E)
4875 .get();
4876 PostUpdate = PostUpdate
4877 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4878 PostUpdate, ConvE)
4879 .get()
4880 : ConvE;
4881 }
4882 }
4883 return PostUpdate;
4884}
4885
4886/// Called on a for stmt to check itself and nested loops (if any).
4887/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4888/// number of collapsed loops otherwise.
4889static unsigned
4890checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4891 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4892 DSAStackTy &DSA,
4893 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4894 OMPLoopDirective::HelperExprs &Built) {
4895 unsigned NestedLoopCount = 1;
4896 if (CollapseLoopCountExpr) {
1
Assuming 'CollapseLoopCountExpr' is null
2
Taking false branch
4897 // Found 'collapse' clause - calculate collapse number.
4898 llvm::APSInt Result;
4899 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4900 NestedLoopCount = Result.getLimitedValue();
4901 }
4902 unsigned OrderedLoopCount = 1;
4903 if (OrderedLoopCountExpr) {
3
Assuming 'OrderedLoopCountExpr' is non-null
4
Taking true branch
4904 // Found 'ordered' clause - calculate collapse number.
4905 llvm::APSInt Result;
4906 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
5
Assuming the condition is true
6
Taking true branch
4907 if (Result.getLimitedValue() < NestedLoopCount) {
7
Assuming the condition is true
8
Taking true branch
4908 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4909 diag::err_omp_wrong_ordered_loop_count)
4910 << OrderedLoopCountExpr->getSourceRange();
4911 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9
Called C++ object pointer is null
4912 diag::note_collapse_loop_count)
4913 << CollapseLoopCountExpr->getSourceRange();
4914 }
4915 OrderedLoopCount = Result.getLimitedValue();
4916 }
4917 }
4918 // This is helper routine for loop directives (e.g., 'for', 'simd',
4919 // 'for simd', etc.).
4920 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
4921 SmallVector<LoopIterationSpace, 4> IterSpaces;
4922 IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
4923 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4924 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4925 if (checkOpenMPIterationSpace(
4926 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4927 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4928 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4929 Captures))
4930 return 0;
4931 // Move on to the next nested for loop, or to the loop body.
4932 // OpenMP [2.8.1, simd construct, Restrictions]
4933 // All loops associated with the construct must be perfectly nested; that
4934 // is, there must be no intervening code nor any OpenMP directive between
4935 // any two loops.
4936 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4937 }
4938 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
4939 if (checkOpenMPIterationSpace(
4940 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4941 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4942 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4943 Captures))
4944 return 0;
4945 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
4946 // Handle initialization of captured loop iterator variables.
4947 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
4948 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
4949 Captures[DRE] = DRE;
4950 }
4951 }
4952 // Move on to the next nested for loop, or to the loop body.
4953 // OpenMP [2.8.1, simd construct, Restrictions]
4954 // All loops associated with the construct must be perfectly nested; that
4955 // is, there must be no intervening code nor any OpenMP directive between
4956 // any two loops.
4957 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4958 }
4959
4960 Built.clear(/* size */ NestedLoopCount);
4961
4962 if (SemaRef.CurContext->isDependentContext())
4963 return NestedLoopCount;
4964
4965 // An example of what is generated for the following code:
4966 //
4967 // #pragma omp simd collapse(2) ordered(2)
4968 // for (i = 0; i < NI; ++i)
4969 // for (k = 0; k < NK; ++k)
4970 // for (j = J0; j < NJ; j+=2) {
4971 // <loop body>
4972 // }
4973 //
4974 // We generate the code below.
4975 // Note: the loop body may be outlined in CodeGen.
4976 // Note: some counters may be C++ classes, operator- is used to find number of
4977 // iterations and operator+= to calculate counter value.
4978 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4979 // or i64 is currently supported).
4980 //
4981 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4982 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4983 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4984 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4985 // // similar updates for vars in clauses (e.g. 'linear')
4986 // <loop body (using local i and j)>
4987 // }
4988 // i = NI; // assign final values of counters
4989 // j = NJ;
4990 //
4991
4992 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4993 // the iteration counts of the collapsed for loops.
4994 // Precondition tests if there is at least one iteration (all conditions are
4995 // true).
4996 auto PreCond = ExprResult(IterSpaces[0].PreCond);
4997 Expr *N0 = IterSpaces[0].NumIterations;
4998 ExprResult LastIteration32 =
4999 widenIterationCount(/*Bits=*/32,
5000 SemaRef
5001 .PerformImplicitConversion(
5002 N0->IgnoreImpCasts(), N0->getType(),
5003 Sema::AA_Converting, /*AllowExplicit=*/true)
5004 .get(),
5005 SemaRef);
5006 ExprResult LastIteration64 = widenIterationCount(
5007 /*Bits=*/64,
5008 SemaRef
5009 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
5010 Sema::AA_Converting,
5011 /*AllowExplicit=*/true)
5012 .get(),
5013 SemaRef);
5014
5015 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
5016 return NestedLoopCount;
5017
5018 ASTContext &C = SemaRef.Context;
5019 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
5020
5021 Scope *CurScope = DSA.getCurScope();
5022 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5023 if (PreCond.isUsable()) {
5024 PreCond =
5025 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
5026 PreCond.get(), IterSpaces[Cnt].PreCond);
5027 }
5028 Expr *N = IterSpaces[Cnt].NumIterations;
5029 SourceLocation Loc = N->getExprLoc();
5030 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5031 if (LastIteration32.isUsable())
5032 LastIteration32 = SemaRef.BuildBinOp(
5033 CurScope, Loc, BO_Mul, LastIteration32.get(),
5034 SemaRef
5035 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5036 Sema::AA_Converting,
5037 /*AllowExplicit=*/true)
5038 .get());
5039 if (LastIteration64.isUsable())
5040 LastIteration64 = SemaRef.BuildBinOp(
5041 CurScope, Loc, BO_Mul, LastIteration64.get(),
5042 SemaRef
5043 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
5044 Sema::AA_Converting,
5045 /*AllowExplicit=*/true)
5046 .get());
5047 }
5048
5049 // Choose either the 32-bit or 64-bit version.
5050 ExprResult LastIteration = LastIteration64;
5051 if (LastIteration32.isUsable() &&
5052 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
5053 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5054 fitsInto(
5055 /*Bits=*/32,
5056 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
5057 LastIteration64.get(), SemaRef)))
5058 LastIteration = LastIteration32;
5059 QualType VType = LastIteration.get()->getType();
5060 QualType RealVType = VType;
5061 QualType StrideVType = VType;
5062 if (isOpenMPTaskLoopDirective(DKind)) {
5063 VType =
5064 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
5065 StrideVType =
5066 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
5067 }
5068
5069 if (!LastIteration.isUsable())
5070 return 0;
5071
5072 // Save the number of iterations.
5073 ExprResult NumIterations = LastIteration;
5074 {
5075 LastIteration = SemaRef.BuildBinOp(
5076 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
5077 LastIteration.get(),
5078 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5079 if (!LastIteration.isUsable())
5080 return 0;
5081 }
5082
5083 // Calculate the last iteration number beforehand instead of doing this on
5084 // each iteration. Do not do this if the number of iterations may be kfold-ed.
5085 llvm::APSInt Result;
5086 bool IsConstant =
5087 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
5088 ExprResult CalcLastIteration;
5089 if (!IsConstant) {
5090 ExprResult SaveRef =
5091 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
5092 LastIteration = SaveRef;
5093
5094 // Prepare SaveRef + 1.
5095 NumIterations = SemaRef.BuildBinOp(
5096 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
5097 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5098 if (!NumIterations.isUsable())
5099 return 0;
5100 }
5101
5102 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5103
5104 // Build variables passed into runtime, necessary for worksharing directives.
5105 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5106 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5107 isOpenMPDistributeDirective(DKind)) {
5108 // Lower bound variable, initialized with zero.
5109 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5110 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5111 SemaRef.AddInitializerToDecl(LBDecl,
5112 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5113 /*DirectInit*/ false);
5114
5115 // Upper bound variable, initialized with last iteration number.
5116 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5117 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5118 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5119 /*DirectInit*/ false);
5120
5121 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5122 // This will be used to implement clause 'lastprivate'.
5123 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5124 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5125 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5126 SemaRef.AddInitializerToDecl(ILDecl,
5127 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5128 /*DirectInit*/ false);
5129
5130 // Stride variable returned by runtime (we initialize it to 1 by default).
5131 VarDecl *STDecl =
5132 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5133 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5134 SemaRef.AddInitializerToDecl(STDecl,
5135 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5136 /*DirectInit*/ false);
5137
5138 // Build expression: UB = min(UB, LastIteration)
5139 // It is necessary for CodeGen of directives with static scheduling.
5140 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5141 UB.get(), LastIteration.get());
5142 ExprResult CondOp = SemaRef.ActOnConditionalOp(
5143 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
5144 LastIteration.get(), UB.get());
5145 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5146 CondOp.get());
5147 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5148
5149 // If we have a combined directive that combines 'distribute', 'for' or
5150 // 'simd' we need to be able to access the bounds of the schedule of the
5151 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5152 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5153 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5154 // Lower bound variable, initialized with zero.
5155 VarDecl *CombLBDecl =
5156 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
5157 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
5158 SemaRef.AddInitializerToDecl(
5159 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5160 /*DirectInit*/ false);
5161
5162 // Upper bound variable, initialized with last iteration number.
5163 VarDecl *CombUBDecl =
5164 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
5165 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
5166 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
5167 /*DirectInit*/ false);
5168
5169 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5170 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
5171 ExprResult CombCondOp =
5172 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
5173 LastIteration.get(), CombUB.get());
5174 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
5175 CombCondOp.get());
5176 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
5177
5178 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5179 // We expect to have at least 2 more parameters than the 'parallel'
5180 // directive does - the lower and upper bounds of the previous schedule.
5181 assert(CD->getNumParams() >= 4 &&((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5182, __PRETTY_FUNCTION__))
5182 "Unexpected number of parameters in loop combined directive")((CD->getNumParams() >= 4 && "Unexpected number of parameters in loop combined directive"
) ? static_cast<void> (0) : __assert_fail ("CD->getNumParams() >= 4 && \"Unexpected number of parameters in loop combined directive\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5182, __PRETTY_FUNCTION__))
;
5183
5184 // Set the proper type for the bounds given what we learned from the
5185 // enclosed loops.
5186 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5187 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5188
5189 // Previous lower and upper bounds are obtained from the region
5190 // parameters.
5191 PrevLB =
5192 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5193 PrevUB =
5194 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5195 }
5196 }
5197
5198 // Build the iteration variable and its initialization before loop.
5199 ExprResult IV;
5200 ExprResult Init, CombInit;
5201 {
5202 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5203 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5204 Expr *RHS =
5205 (isOpenMPWorksharingDirective(DKind) ||
5206 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5207 ? LB.get()
5208 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5209 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5210 Init = SemaRef.ActOnFinishFullExpr(Init.get());
5211
5212 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5213 Expr *CombRHS =
5214 (isOpenMPWorksharingDirective(DKind) ||
5215 isOpenMPTaskLoopDirective(DKind) ||
5216 isOpenMPDistributeDirective(DKind))
5217 ? CombLB.get()
5218 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5219 CombInit =
5220 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5221 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
5222 }
5223 }
5224
5225 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5226 SourceLocation CondLoc = AStmt->getBeginLoc();
5227 ExprResult Cond =
5228 (isOpenMPWorksharingDirective(DKind) ||
5229 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
5230 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5231 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5232 NumIterations.get());
5233 ExprResult CombCond;
5234 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5235 CombCond =
5236 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5237 }
5238 // Loop increment (IV = IV + 1)
5239 SourceLocation IncLoc = AStmt->getBeginLoc();
5240 ExprResult Inc =
5241 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5242 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5243 if (!Inc.isUsable())
5244 return 0;
5245 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5246 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5247 if (!Inc.isUsable())
5248 return 0;
5249
5250 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5251 // Used for directives with static scheduling.
5252 // In combined construct, add combined version that use CombLB and CombUB
5253 // base variables for the update
5254 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5255 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
5256 isOpenMPDistributeDirective(DKind)) {
5257 // LB + ST
5258 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5259 if (!NextLB.isUsable())
5260 return 0;
5261 // LB = LB + ST
5262 NextLB =
5263 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5264 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5265 if (!NextLB.isUsable())
5266 return 0;
5267 // UB + ST
5268 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5269 if (!NextUB.isUsable())
5270 return 0;
5271 // UB = UB + ST
5272 NextUB =
5273 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5274 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5275 if (!NextUB.isUsable())
5276 return 0;
5277 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5278 CombNextLB =
5279 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5280 if (!NextLB.isUsable())
5281 return 0;
5282 // LB = LB + ST
5283 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5284 CombNextLB.get());
5285 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
5286 if (!CombNextLB.isUsable())
5287 return 0;
5288 // UB + ST
5289 CombNextUB =
5290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5291 if (!CombNextUB.isUsable())
5292 return 0;
5293 // UB = UB + ST
5294 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5295 CombNextUB.get());
5296 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
5297 if (!CombNextUB.isUsable())
5298 return 0;
5299 }
5300 }
5301
5302 // Create increment expression for distribute loop when combined in a same
5303 // directive with for as IV = IV + ST; ensure upper bound expression based
5304 // on PrevUB instead of NumIterations - used to implement 'for' when found
5305 // in combination with 'distribute', like in 'distribute parallel for'
5306 SourceLocation DistIncLoc = AStmt->getBeginLoc();
5307 ExprResult DistCond, DistInc, PrevEUB;
5308 if (isOpenMPLoopBoundSharingDirective(DKind)) {
5309 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5310 assert(DistCond.isUsable() && "distribute cond expr was not built")((DistCond.isUsable() && "distribute cond expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistCond.isUsable() && \"distribute cond expr was not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5310, __PRETTY_FUNCTION__))
;
5311
5312 DistInc =
5313 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5314 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5314, __PRETTY_FUNCTION__))
;
5315 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5316 DistInc.get());
5317 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
5318 assert(DistInc.isUsable() && "distribute inc expr was not built")((DistInc.isUsable() && "distribute inc expr was not built"
) ? static_cast<void> (0) : __assert_fail ("DistInc.isUsable() && \"distribute inc expr was not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5318, __PRETTY_FUNCTION__))
;
5319
5320 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5321 // construct
5322 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
5323 ExprResult IsUBGreater =
5324 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5325 ExprResult CondOp = SemaRef.ActOnConditionalOp(
5326 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5327 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5328 CondOp.get());
5329 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
5330 }
5331
5332 // Build updates and final values of the loop counters.
5333 bool HasErrors = false;
5334 Built.Counters.resize(NestedLoopCount);
5335 Built.Inits.resize(NestedLoopCount);
5336 Built.Updates.resize(NestedLoopCount);
5337 Built.Finals.resize(NestedLoopCount);
5338 {
5339 ExprResult Div;
5340 // Go from inner nested loop to outer.
5341 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5342 LoopIterationSpace &IS = IterSpaces[Cnt];
5343 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5344 // Build: Iter = (IV / Div) % IS.NumIters
5345 // where Div is product of previous iterations' IS.NumIters.
5346 ExprResult Iter;
5347 if (Div.isUsable()) {
5348 Iter =
5349 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
5350 } else {
5351 Iter = IV;
5352 assert((Cnt == (int)NestedLoopCount - 1) &&(((Cnt == (int)NestedLoopCount - 1) && "unusable div expected on first iteration only"
) ? static_cast<void> (0) : __assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5353, __PRETTY_FUNCTION__))
5353 "unusable div expected on first iteration only")(((Cnt == (int)NestedLoopCount - 1) && "unusable div expected on first iteration only"
) ? static_cast<void> (0) : __assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5353, __PRETTY_FUNCTION__))
;
5354 }
5355
5356 if (Cnt != 0 && Iter.isUsable())
5357 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
5358 IS.NumIterations);
5359 if (!Iter.isUsable()) {
5360 HasErrors = true;
5361 break;
5362 }
5363
5364 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5365 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5366 DeclRefExpr *CounterVar = buildDeclRefExpr(
5367 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5368 /*RefersToCapture=*/true);
5369 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5370 IS.CounterInit, Captures);
5371 if (!Init.isUsable()) {
5372 HasErrors = true;
5373 break;
5374 }
5375 ExprResult Update = buildCounterUpdate(
5376 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5377 IS.CounterStep, IS.Subtract, &Captures);
5378 if (!Update.isUsable()) {
5379 HasErrors = true;
5380 break;
5381 }
5382
5383 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5384 ExprResult Final = buildCounterUpdate(
5385 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5386 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5387 if (!Final.isUsable()) {
5388 HasErrors = true;
5389 break;
5390 }
5391
5392 // Build Div for the next iteration: Div <- Div * IS.NumIters
5393 if (Cnt != 0) {
5394 if (Div.isUnset())
5395 Div = IS.NumIterations;
5396 else
5397 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
5398 IS.NumIterations);
5399
5400 // Add parentheses (for debugging purposes only).
5401 if (Div.isUsable())
5402 Div = tryBuildCapture(SemaRef, Div.get(), Captures);
5403 if (!Div.isUsable()) {
5404 HasErrors = true;
5405 break;
5406 }
5407 }
5408 if (!Update.isUsable() || !Final.isUsable()) {
5409 HasErrors = true;
5410 break;
5411 }
5412 // Save results
5413 Built.Counters[Cnt] = IS.CounterVar;
5414 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5415 Built.Inits[Cnt] = Init.get();
5416 Built.Updates[Cnt] = Update.get();
5417 Built.Finals[Cnt] = Final.get();
5418 }
5419 }
5420
5421 if (HasErrors)
5422 return 0;
5423
5424 // Save results
5425 Built.IterationVarRef = IV.get();
5426 Built.LastIteration = LastIteration.get();
5427 Built.NumIterations = NumIterations.get();
5428 Built.CalcLastIteration =
5429 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5430 Built.PreCond = PreCond.get();
5431 Built.PreInits = buildPreInits(C, Captures);
5432 Built.Cond = Cond.get();
5433 Built.Init = Init.get();
5434 Built.Inc = Inc.get();
5435 Built.LB = LB.get();
5436 Built.UB = UB.get();
5437 Built.IL = IL.get();
5438 Built.ST = ST.get();
5439 Built.EUB = EUB.get();
5440 Built.NLB = NextLB.get();
5441 Built.NUB = NextUB.get();
5442 Built.PrevLB = PrevLB.get();
5443 Built.PrevUB = PrevUB.get();
5444 Built.DistInc = DistInc.get();
5445 Built.PrevEUB = PrevEUB.get();
5446 Built.DistCombinedFields.LB = CombLB.get();
5447 Built.DistCombinedFields.UB = CombUB.get();
5448 Built.DistCombinedFields.EUB = CombEUB.get();
5449 Built.DistCombinedFields.Init = CombInit.get();
5450 Built.DistCombinedFields.Cond = CombCond.get();
5451 Built.DistCombinedFields.NLB = CombNextLB.get();
5452 Built.DistCombinedFields.NUB = CombNextUB.get();
5453
5454 return NestedLoopCount;
5455}
5456
5457static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5458 auto CollapseClauses =
5459 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5460 if (CollapseClauses.begin() != CollapseClauses.end())
5461 return (*CollapseClauses.begin())->getNumForLoops();
5462 return nullptr;
5463}
5464
5465static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5466 auto OrderedClauses =
5467 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5468 if (OrderedClauses.begin() != OrderedClauses.end())
5469 return (*OrderedClauses.begin())->getNumForLoops();
5470 return nullptr;
5471}
5472
5473static bool checkSimdlenSafelenSpecified(Sema &S,
5474 const ArrayRef<OMPClause *> Clauses) {
5475 const OMPSafelenClause *Safelen = nullptr;
5476 const OMPSimdlenClause *Simdlen = nullptr;
5477
5478 for (const OMPClause *Clause : Clauses) {
5479 if (Clause->getClauseKind() == OMPC_safelen)
5480 Safelen = cast<OMPSafelenClause>(Clause);
5481 else if (Clause->getClauseKind() == OMPC_simdlen)
5482 Simdlen = cast<OMPSimdlenClause>(Clause);
5483 if (Safelen && Simdlen)
5484 break;
5485 }
5486
5487 if (Simdlen && Safelen) {
5488 llvm::APSInt SimdlenRes, SafelenRes;
5489 const Expr *SimdlenLength = Simdlen->getSimdlen();
5490 const Expr *SafelenLength = Safelen->getSafelen();
5491 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5492 SimdlenLength->isInstantiationDependent() ||
5493 SimdlenLength->containsUnexpandedParameterPack())
5494 return false;
5495 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5496 SafelenLength->isInstantiationDependent() ||
5497 SafelenLength->containsUnexpandedParameterPack())
5498 return false;
5499 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5500 SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5501 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5502 // If both simdlen and safelen clauses are specified, the value of the
5503 // simdlen parameter must be less than or equal to the value of the safelen
5504 // parameter.
5505 if (SimdlenRes > SafelenRes) {
5506 S.Diag(SimdlenLength->getExprLoc(),
5507 diag::err_omp_wrong_simdlen_safelen_values)
5508 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5509 return true;
5510 }
5511 }
5512 return false;
5513}
5514
5515StmtResult
5516Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5517 SourceLocation StartLoc, SourceLocation EndLoc,
5518 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5519 if (!AStmt)
5520 return StmtError();
5521
5522 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5522, __PRETTY_FUNCTION__))
;
5523 OMPLoopDirective::HelperExprs B;
5524 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5525 // define the nested loops number.
5526 unsigned NestedLoopCount = checkOpenMPLoop(
5527 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5528 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5529 if (NestedLoopCount == 0)
5530 return StmtError();
5531
5532 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5533, __PRETTY_FUNCTION__))
5533 "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp simd loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5533, __PRETTY_FUNCTION__))
;
5534
5535 if (!CurContext->isDependentContext()) {
5536 // Finalize the clauses that need pre-built expressions for CodeGen.
5537 for (OMPClause *C : Clauses) {
5538 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5539 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5540 B.NumIterations, *this, CurScope,
5541 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5542 return StmtError();
5543 }
5544 }
5545
5546 if (checkSimdlenSafelenSpecified(*this, Clauses))
5547 return StmtError();
5548
5549 setFunctionHasBranchProtectedScope();
5550 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5551 Clauses, AStmt, B);
5552}
5553
5554StmtResult
5555Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
5556 SourceLocation StartLoc, SourceLocation EndLoc,
5557 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5558 if (!AStmt)
5559 return StmtError();
5560
5561 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5561, __PRETTY_FUNCTION__))
;
5562 OMPLoopDirective::HelperExprs B;
5563 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5564 // define the nested loops number.
5565 unsigned NestedLoopCount = checkOpenMPLoop(
5566 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5567 AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
, VarsWithImplicitDSA, B);
5568 if (NestedLoopCount == 0)
5569 return StmtError();
5570
5571 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5572, __PRETTY_FUNCTION__))
5572 "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for loop exprs were not built") ? static_cast<void>
(0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5572, __PRETTY_FUNCTION__))
;
5573
5574 if (!CurContext->isDependentContext()) {
5575 // Finalize the clauses that need pre-built expressions for CodeGen.
5576 for (OMPClause *C : Clauses) {
5577 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5578 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5579 B.NumIterations, *this, CurScope,
5580 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5581 return StmtError();
5582 }
5583 }
5584
5585 setFunctionHasBranchProtectedScope();
5586 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5587 Clauses, AStmt, B, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5588}
5589
5590StmtResult Sema::ActOnOpenMPForSimdDirective(
5591 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5592 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5593 if (!AStmt)
5594 return StmtError();
5595
5596 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5596, __PRETTY_FUNCTION__))
;
5597 OMPLoopDirective::HelperExprs B;
5598 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5599 // define the nested loops number.
5600 unsigned NestedLoopCount =
5601 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5602 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
,
5603 VarsWithImplicitDSA, B);
5604 if (NestedLoopCount == 0)
5605 return StmtError();
5606
5607 assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5608, __PRETTY_FUNCTION__))
5608 "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) &&
"omp for simd loop exprs were not built") ? static_cast<void
> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5608, __PRETTY_FUNCTION__))
;
5609
5610 if (!CurContext->isDependentContext()) {
5611 // Finalize the clauses that need pre-built expressions for CodeGen.
5612 for (OMPClause *C : Clauses) {
5613 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5614 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5615 B.NumIterations, *this, CurScope,
5616 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
))
5617 return StmtError();
5618 }
5619 }
5620
5621 if (checkSimdlenSafelenSpecified(*this, Clauses))
5622 return StmtError();
5623
5624 setFunctionHasBranchProtectedScope();
5625 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5626 Clauses, AStmt, B);
5627}
5628
5629StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5630 Stmt *AStmt,
5631 SourceLocation StartLoc,
5632 SourceLocation EndLoc) {
5633 if (!AStmt)
5634 return StmtError();
5635
5636 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5636, __PRETTY_FUNCTION__))
;
5637 auto BaseStmt = AStmt;
5638 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5639 BaseStmt = CS->getCapturedStmt();
5640 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5641 auto S = C->children();
5642 if (S.begin() == S.end())
5643 return StmtError();
5644 // All associated statements must be '#pragma omp section' except for
5645 // the first one.
5646 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5647 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5648 if (SectionStmt)
5649 Diag(SectionStmt->getBeginLoc(),
5650 diag::err_omp_sections_substmt_not_section);
5651 return StmtError();
5652 }
5653 cast<OMPSectionDirective>(SectionStmt)
5654 ->setHasCancel(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5655 }
5656 } else {
5657 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
5658 return StmtError();
5659 }
5660
5661 setFunctionHasBranchProtectedScope();
5662
5663 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5664 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5665}
5666
5667StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5668 SourceLocation StartLoc,
5669 SourceLocation EndLoc) {
5670 if (!AStmt)
5671 return StmtError();
5672
5673 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5673, __PRETTY_FUNCTION__))
;
5674
5675 setFunctionHasBranchProtectedScope();
5676 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->setParentCancelRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5677
5678 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5679 DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack
)
->isCancelRegion());
5680}
5681
5682StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5683 Stmt *AStmt,
5684 SourceLocation StartLoc,
5685 SourceLocation EndLoc) {
5686 if (!AStmt)
5687 return StmtError();
5688
5689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5689, __PRETTY_FUNCTION__))
;
5690
5691 setFunctionHasBranchProtectedScope();
5692
5693 // OpenMP [2.7.3, single Construct, Restrictions]
5694 // The copyprivate clause must not be used with the nowait clause.
5695 const OMPClause *Nowait = nullptr;
5696 const OMPClause *Copyprivate = nullptr;
5697 for (const OMPClause *Clause : Clauses) {
5698 if (Clause->getClauseKind() == OMPC_nowait)
5699 Nowait = Clause;
5700 else if (Clause->getClauseKind() == OMPC_copyprivate)
5701 Copyprivate = Clause;
5702 if (Copyprivate && Nowait) {
5703 Diag(Copyprivate->getBeginLoc(),
5704 diag::err_omp_single_copyprivate_with_nowait);
5705 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
5706 return StmtError();
5707 }
5708 }
5709
5710 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5711}
5712
5713StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5714 SourceLocation StartLoc,
5715 SourceLocation EndLoc) {
5716 if (!AStmt)
5717 return StmtError();
5718
5719 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected")((isa<CapturedStmt>(AStmt) && "Captured statement expected"
) ? static_cast<void> (0) : __assert_fail ("isa<CapturedStmt>(AStmt) && \"Captured statement expected\""
, "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/lib/Sema/SemaOpenMP.cpp"
, 5719, __PRETTY_FUNCTION__))
;
5720
5721 setFunctionHasBranchProtectedScope();
5722
5723 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5724}