Bug Summary

File:build-llvm/tools/clang/include/clang/AST/Attrs.inc
Warning:line 5977, column 5
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 -analyzer-config-compatibility-mode=true -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-9/lib/clang/9.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn361465/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/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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-9~svn361465/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn361465=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -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-2019-05-24-031927-21217-1 -x c++ /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema/SemaOpenMP.cpp -faddrsig

/build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema/SemaOpenMP.cpp

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