File: | tools/clang/lib/Sema/SemaOpenMP.cpp |
Location: | line 2616, column 20 |
Description: | Called C++ object pointer is null |
1 | //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | /// \file | |||
10 | /// \brief This file implements semantic analysis for OpenMP directives and | |||
11 | /// clauses. | |||
12 | /// | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "clang/AST/ASTContext.h" | |||
16 | #include "clang/AST/ASTMutationListener.h" | |||
17 | #include "clang/AST/Decl.h" | |||
18 | #include "clang/AST/DeclCXX.h" | |||
19 | #include "clang/AST/DeclOpenMP.h" | |||
20 | #include "clang/AST/StmtCXX.h" | |||
21 | #include "clang/AST/StmtOpenMP.h" | |||
22 | #include "clang/AST/StmtVisitor.h" | |||
23 | #include "clang/Basic/OpenMPKinds.h" | |||
24 | #include "clang/Lex/Preprocessor.h" | |||
25 | #include "clang/Sema/Initialization.h" | |||
26 | #include "clang/Sema/Lookup.h" | |||
27 | #include "clang/Sema/Scope.h" | |||
28 | #include "clang/Sema/ScopeInfo.h" | |||
29 | #include "clang/Sema/SemaInternal.h" | |||
30 | using namespace clang; | |||
31 | ||||
32 | //===----------------------------------------------------------------------===// | |||
33 | // Stack of data-sharing attributes for variables | |||
34 | //===----------------------------------------------------------------------===// | |||
35 | ||||
36 | namespace { | |||
37 | /// \brief Default data sharing attributes, which can be applied to directive. | |||
38 | enum DefaultDataSharingAttributes { | |||
39 | DSA_unspecified = 0, /// \brief Data sharing attribute not specified. | |||
40 | DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. | |||
41 | DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. | |||
42 | }; | |||
43 | ||||
44 | template <class T> struct MatchesAny { | |||
45 | explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} | |||
46 | bool operator()(T Kind) { | |||
47 | for (auto KindEl : Arr) | |||
48 | if (KindEl == Kind) | |||
49 | return true; | |||
50 | return false; | |||
51 | } | |||
52 | ||||
53 | private: | |||
54 | ArrayRef<T> Arr; | |||
55 | }; | |||
56 | struct MatchesAlways { | |||
57 | MatchesAlways() {} | |||
58 | template <class T> bool operator()(T) { return true; } | |||
59 | }; | |||
60 | ||||
61 | typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; | |||
62 | typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; | |||
63 | ||||
64 | /// \brief Stack for tracking declarations used in OpenMP directives and | |||
65 | /// clauses and their data-sharing attributes. | |||
66 | class DSAStackTy { | |||
67 | public: | |||
68 | struct DSAVarData { | |||
69 | OpenMPDirectiveKind DKind; | |||
70 | OpenMPClauseKind CKind; | |||
71 | DeclRefExpr *RefExpr; | |||
72 | SourceLocation ImplicitDSALoc; | |||
73 | DSAVarData() | |||
74 | : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), | |||
75 | ImplicitDSALoc() {} | |||
76 | }; | |||
77 | ||||
78 | private: | |||
79 | struct DSAInfo { | |||
80 | OpenMPClauseKind Attributes; | |||
81 | DeclRefExpr *RefExpr; | |||
82 | }; | |||
83 | typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; | |||
84 | typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; | |||
85 | typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy; | |||
86 | ||||
87 | struct SharingMapTy { | |||
88 | DeclSAMapTy SharingMap; | |||
89 | AlignedMapTy AlignedMap; | |||
90 | LoopControlVariablesSetTy LCVSet; | |||
91 | DefaultDataSharingAttributes DefaultAttr; | |||
92 | SourceLocation DefaultAttrLoc; | |||
93 | OpenMPDirectiveKind Directive; | |||
94 | DeclarationNameInfo DirectiveName; | |||
95 | Scope *CurScope; | |||
96 | SourceLocation ConstructLoc; | |||
97 | bool OrderedRegion; | |||
98 | unsigned CollapseNumber; | |||
99 | SourceLocation InnerTeamsRegionLoc; | |||
100 | SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, | |||
101 | Scope *CurScope, SourceLocation Loc) | |||
102 | : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), | |||
103 | Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), | |||
104 | ConstructLoc(Loc), OrderedRegion(false), CollapseNumber(1), | |||
105 | InnerTeamsRegionLoc() {} | |||
106 | SharingMapTy() | |||
107 | : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), | |||
108 | Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), | |||
109 | ConstructLoc(), OrderedRegion(false), CollapseNumber(1), | |||
110 | InnerTeamsRegionLoc() {} | |||
111 | }; | |||
112 | ||||
113 | typedef SmallVector<SharingMapTy, 64> StackTy; | |||
114 | ||||
115 | /// \brief Stack of used declaration and their data-sharing attributes. | |||
116 | StackTy Stack; | |||
117 | /// \brief true, if check for DSA must be from parent directive, false, if | |||
118 | /// from current directive. | |||
119 | OpenMPClauseKind ClauseKindMode; | |||
120 | Sema &SemaRef; | |||
121 | ||||
122 | typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; | |||
123 | ||||
124 | DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); | |||
125 | ||||
126 | /// \brief Checks if the variable is a local for OpenMP region. | |||
127 | bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); | |||
128 | ||||
129 | public: | |||
130 | explicit DSAStackTy(Sema &S) | |||
131 | : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S) {} | |||
132 | ||||
133 | bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } | |||
134 | void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } | |||
135 | ||||
136 | void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, | |||
137 | Scope *CurScope, SourceLocation Loc) { | |||
138 | Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); | |||
139 | Stack.back().DefaultAttrLoc = Loc; | |||
140 | } | |||
141 | ||||
142 | void pop() { | |||
143 | assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!")((Stack.size() > 1 && "Data-sharing attributes stack is empty!" ) ? static_cast<void> (0) : __assert_fail ("Stack.size() > 1 && \"Data-sharing attributes stack is empty!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 143, __PRETTY_FUNCTION__)); | |||
144 | Stack.pop_back(); | |||
145 | } | |||
146 | ||||
147 | /// \brief If 'aligned' declaration for given variable \a D was not seen yet, | |||
148 | /// add it and return NULL; otherwise return previous occurrence's expression | |||
149 | /// for diagnostics. | |||
150 | DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE); | |||
151 | ||||
152 | /// \brief Register specified variable as loop control variable. | |||
153 | void addLoopControlVariable(VarDecl *D); | |||
154 | /// \brief Check if the specified variable is a loop control variable for | |||
155 | /// current region. | |||
156 | bool isLoopControlVariable(VarDecl *D); | |||
157 | ||||
158 | /// \brief Adds explicit data sharing attribute to the specified declaration. | |||
159 | void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); | |||
160 | ||||
161 | /// \brief Returns data sharing attributes from top of the stack for the | |||
162 | /// specified declaration. | |||
163 | DSAVarData getTopDSA(VarDecl *D, bool FromParent); | |||
164 | /// \brief Returns data-sharing attributes for the specified declaration. | |||
165 | DSAVarData getImplicitDSA(VarDecl *D, bool FromParent); | |||
166 | /// \brief Checks if the specified variables has data-sharing attributes which | |||
167 | /// match specified \a CPred predicate in any directive which matches \a DPred | |||
168 | /// predicate. | |||
169 | template <class ClausesPredicate, class DirectivesPredicate> | |||
170 | DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred, | |||
171 | DirectivesPredicate DPred, bool FromParent); | |||
172 | /// \brief Checks if the specified variables has data-sharing attributes which | |||
173 | /// match specified \a CPred predicate in any innermost directive which | |||
174 | /// matches \a DPred predicate. | |||
175 | template <class ClausesPredicate, class DirectivesPredicate> | |||
176 | DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, | |||
177 | DirectivesPredicate DPred, | |||
178 | bool FromParent); | |||
179 | /// \brief Checks if the specified variables has explicit data-sharing | |||
180 | /// attributes which match specified \a CPred predicate at the specified | |||
181 | /// OpenMP region. | |||
182 | bool hasExplicitDSA(VarDecl *D, | |||
183 | const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | |||
184 | unsigned Level); | |||
185 | /// \brief Finds a directive which matches specified \a DPred predicate. | |||
186 | template <class NamedDirectivesPredicate> | |||
187 | bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); | |||
188 | ||||
189 | /// \brief Returns currently analyzed directive. | |||
190 | OpenMPDirectiveKind getCurrentDirective() const { | |||
191 | return Stack.back().Directive; | |||
192 | } | |||
193 | /// \brief Returns parent directive. | |||
194 | OpenMPDirectiveKind getParentDirective() const { | |||
195 | if (Stack.size() > 2) | |||
196 | return Stack[Stack.size() - 2].Directive; | |||
197 | return OMPD_unknown; | |||
198 | } | |||
199 | ||||
200 | /// \brief Set default data sharing attribute to none. | |||
201 | void setDefaultDSANone(SourceLocation Loc) { | |||
202 | Stack.back().DefaultAttr = DSA_none; | |||
203 | Stack.back().DefaultAttrLoc = Loc; | |||
204 | } | |||
205 | /// \brief Set default data sharing attribute to shared. | |||
206 | void setDefaultDSAShared(SourceLocation Loc) { | |||
207 | Stack.back().DefaultAttr = DSA_shared; | |||
208 | Stack.back().DefaultAttrLoc = Loc; | |||
209 | } | |||
210 | ||||
211 | DefaultDataSharingAttributes getDefaultDSA() const { | |||
212 | return Stack.back().DefaultAttr; | |||
213 | } | |||
214 | SourceLocation getDefaultDSALocation() const { | |||
215 | return Stack.back().DefaultAttrLoc; | |||
216 | } | |||
217 | ||||
218 | /// \brief Checks if the specified variable is a threadprivate. | |||
219 | bool isThreadPrivate(VarDecl *D) { | |||
220 | DSAVarData DVar = getTopDSA(D, false); | |||
221 | return isOpenMPThreadPrivate(DVar.CKind); | |||
222 | } | |||
223 | ||||
224 | /// \brief Marks current region as ordered (it has an 'ordered' clause). | |||
225 | void setOrderedRegion(bool IsOrdered = true) { | |||
226 | Stack.back().OrderedRegion = IsOrdered; | |||
227 | } | |||
228 | /// \brief Returns true, if parent region is ordered (has associated | |||
229 | /// 'ordered' clause), false - otherwise. | |||
230 | bool isParentOrderedRegion() const { | |||
231 | if (Stack.size() > 2) | |||
232 | return Stack[Stack.size() - 2].OrderedRegion; | |||
233 | return false; | |||
234 | } | |||
235 | ||||
236 | /// \brief Set collapse value for the region. | |||
237 | void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; } | |||
238 | /// \brief Return collapse value for region. | |||
239 | unsigned getCollapseNumber() const { | |||
240 | return Stack.back().CollapseNumber; | |||
241 | } | |||
242 | ||||
243 | /// \brief Marks current target region as one with closely nested teams | |||
244 | /// region. | |||
245 | void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { | |||
246 | if (Stack.size() > 2) | |||
247 | Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; | |||
248 | } | |||
249 | /// \brief Returns true, if current region has closely nested teams region. | |||
250 | bool hasInnerTeamsRegion() const { | |||
251 | return getInnerTeamsRegionLoc().isValid(); | |||
252 | } | |||
253 | /// \brief Returns location of the nested teams region (if any). | |||
254 | SourceLocation getInnerTeamsRegionLoc() const { | |||
255 | if (Stack.size() > 1) | |||
256 | return Stack.back().InnerTeamsRegionLoc; | |||
257 | return SourceLocation(); | |||
258 | } | |||
259 | ||||
260 | Scope *getCurScope() const { return Stack.back().CurScope; } | |||
261 | Scope *getCurScope() { return Stack.back().CurScope; } | |||
262 | SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } | |||
263 | }; | |||
264 | bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { | |||
265 | return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || | |||
266 | isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; | |||
267 | } | |||
268 | } // namespace | |||
269 | ||||
270 | DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, | |||
271 | VarDecl *D) { | |||
272 | D = D->getCanonicalDecl(); | |||
273 | DSAVarData DVar; | |||
274 | if (Iter == std::prev(Stack.rend())) { | |||
275 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
276 | // in a region but not in construct] | |||
277 | // File-scope or namespace-scope variables referenced in called routines | |||
278 | // in the region are shared unless they appear in a threadprivate | |||
279 | // directive. | |||
280 | if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) | |||
281 | DVar.CKind = OMPC_shared; | |||
282 | ||||
283 | // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced | |||
284 | // in a region but not in construct] | |||
285 | // Variables with static storage duration that are declared in called | |||
286 | // routines in the region are shared. | |||
287 | if (D->hasGlobalStorage()) | |||
288 | DVar.CKind = OMPC_shared; | |||
289 | ||||
290 | return DVar; | |||
291 | } | |||
292 | ||||
293 | DVar.DKind = Iter->Directive; | |||
294 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
295 | // in a Construct, C/C++, predetermined, p.1] | |||
296 | // Variables with automatic storage duration that are declared in a scope | |||
297 | // inside the construct are private. | |||
298 | if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() && | |||
299 | (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { | |||
300 | DVar.CKind = OMPC_private; | |||
301 | return DVar; | |||
302 | } | |||
303 | ||||
304 | // Explicitly specified attributes and local variables with predetermined | |||
305 | // attributes. | |||
306 | if (Iter->SharingMap.count(D)) { | |||
307 | DVar.RefExpr = Iter->SharingMap[D].RefExpr; | |||
308 | DVar.CKind = Iter->SharingMap[D].Attributes; | |||
309 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | |||
310 | return DVar; | |||
311 | } | |||
312 | ||||
313 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
314 | // in a Construct, C/C++, implicitly determined, p.1] | |||
315 | // In a parallel or task construct, the data-sharing attributes of these | |||
316 | // variables are determined by the default clause, if present. | |||
317 | switch (Iter->DefaultAttr) { | |||
318 | case DSA_shared: | |||
319 | DVar.CKind = OMPC_shared; | |||
320 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | |||
321 | return DVar; | |||
322 | case DSA_none: | |||
323 | return DVar; | |||
324 | case DSA_unspecified: | |||
325 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
326 | // in a Construct, implicitly determined, p.2] | |||
327 | // In a parallel construct, if no default clause is present, these | |||
328 | // variables are shared. | |||
329 | DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; | |||
330 | if (isOpenMPParallelDirective(DVar.DKind) || | |||
331 | isOpenMPTeamsDirective(DVar.DKind)) { | |||
332 | DVar.CKind = OMPC_shared; | |||
333 | return DVar; | |||
334 | } | |||
335 | ||||
336 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
337 | // in a Construct, implicitly determined, p.4] | |||
338 | // In a task construct, if no default clause is present, a variable that in | |||
339 | // the enclosing context is determined to be shared by all implicit tasks | |||
340 | // bound to the current team is shared. | |||
341 | if (DVar.DKind == OMPD_task) { | |||
342 | DSAVarData DVarTemp; | |||
343 | for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); | |||
344 | I != EE; ++I) { | |||
345 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables | |||
346 | // Referenced | |||
347 | // in a Construct, implicitly determined, p.6] | |||
348 | // In a task construct, if no default clause is present, a variable | |||
349 | // whose data-sharing attribute is not determined by the rules above is | |||
350 | // firstprivate. | |||
351 | DVarTemp = getDSA(I, D); | |||
352 | if (DVarTemp.CKind != OMPC_shared) { | |||
353 | DVar.RefExpr = nullptr; | |||
354 | DVar.DKind = OMPD_task; | |||
355 | DVar.CKind = OMPC_firstprivate; | |||
356 | return DVar; | |||
357 | } | |||
358 | if (isParallelOrTaskRegion(I->Directive)) | |||
359 | break; | |||
360 | } | |||
361 | DVar.DKind = OMPD_task; | |||
362 | DVar.CKind = | |||
363 | (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; | |||
364 | return DVar; | |||
365 | } | |||
366 | } | |||
367 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
368 | // in a Construct, implicitly determined, p.3] | |||
369 | // For constructs other than task, if no default clause is present, these | |||
370 | // variables inherit their data-sharing attributes from the enclosing | |||
371 | // context. | |||
372 | return getDSA(std::next(Iter), D); | |||
373 | } | |||
374 | ||||
375 | DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) { | |||
376 | assert(Stack.size() > 1 && "Data sharing attributes stack is empty")((Stack.size() > 1 && "Data sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("Stack.size() > 1 && \"Data sharing attributes stack is empty\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 376, __PRETTY_FUNCTION__)); | |||
377 | D = D->getCanonicalDecl(); | |||
378 | auto It = Stack.back().AlignedMap.find(D); | |||
379 | if (It == Stack.back().AlignedMap.end()) { | |||
380 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 380, __PRETTY_FUNCTION__)); | |||
381 | Stack.back().AlignedMap[D] = NewDE; | |||
382 | return nullptr; | |||
383 | } else { | |||
384 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 384, __PRETTY_FUNCTION__)); | |||
385 | return It->second; | |||
386 | } | |||
387 | return nullptr; | |||
388 | } | |||
389 | ||||
390 | void DSAStackTy::addLoopControlVariable(VarDecl *D) { | |||
391 | assert(Stack.size() > 1 && "Data-sharing attributes stack is empty")((Stack.size() > 1 && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("Stack.size() > 1 && \"Data-sharing attributes stack is empty\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 391, __PRETTY_FUNCTION__)); | |||
392 | D = D->getCanonicalDecl(); | |||
393 | Stack.back().LCVSet.insert(D); | |||
394 | } | |||
395 | ||||
396 | bool DSAStackTy::isLoopControlVariable(VarDecl *D) { | |||
397 | assert(Stack.size() > 1 && "Data-sharing attributes stack is empty")((Stack.size() > 1 && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("Stack.size() > 1 && \"Data-sharing attributes stack is empty\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 397, __PRETTY_FUNCTION__)); | |||
398 | D = D->getCanonicalDecl(); | |||
399 | return Stack.back().LCVSet.count(D) > 0; | |||
400 | } | |||
401 | ||||
402 | void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { | |||
403 | D = D->getCanonicalDecl(); | |||
404 | if (A == OMPC_threadprivate) { | |||
405 | Stack[0].SharingMap[D].Attributes = A; | |||
406 | Stack[0].SharingMap[D].RefExpr = E; | |||
407 | } else { | |||
408 | assert(Stack.size() > 1 && "Data-sharing attributes stack is empty")((Stack.size() > 1 && "Data-sharing attributes stack is empty" ) ? static_cast<void> (0) : __assert_fail ("Stack.size() > 1 && \"Data-sharing attributes stack is empty\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 408, __PRETTY_FUNCTION__)); | |||
409 | Stack.back().SharingMap[D].Attributes = A; | |||
410 | Stack.back().SharingMap[D].RefExpr = E; | |||
411 | } | |||
412 | } | |||
413 | ||||
414 | bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { | |||
415 | D = D->getCanonicalDecl(); | |||
416 | if (Stack.size() > 2) { | |||
417 | reverse_iterator I = Iter, E = std::prev(Stack.rend()); | |||
418 | Scope *TopScope = nullptr; | |||
419 | while (I != E && !isParallelOrTaskRegion(I->Directive)) { | |||
420 | ++I; | |||
421 | } | |||
422 | if (I == E) | |||
423 | return false; | |||
424 | TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; | |||
425 | Scope *CurScope = getCurScope(); | |||
426 | while (CurScope != TopScope && !CurScope->isDeclScope(D)) { | |||
427 | CurScope = CurScope->getParent(); | |||
428 | } | |||
429 | return CurScope != TopScope; | |||
430 | } | |||
431 | return false; | |||
432 | } | |||
433 | ||||
434 | /// \brief Build a variable declaration for OpenMP loop iteration variable. | |||
435 | static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, | |||
436 | StringRef Name) { | |||
437 | DeclContext *DC = SemaRef.CurContext; | |||
438 | IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); | |||
439 | TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); | |||
440 | VarDecl *Decl = | |||
441 | VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); | |||
442 | Decl->setImplicit(); | |||
443 | return Decl; | |||
444 | } | |||
445 | ||||
446 | static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, | |||
447 | SourceLocation Loc, | |||
448 | bool RefersToCapture = false) { | |||
449 | D->setReferenced(); | |||
450 | D->markUsed(S.Context); | |||
451 | return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), | |||
452 | SourceLocation(), D, RefersToCapture, Loc, Ty, | |||
453 | VK_LValue); | |||
454 | } | |||
455 | ||||
456 | DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { | |||
457 | D = D->getCanonicalDecl(); | |||
458 | DSAVarData DVar; | |||
459 | ||||
460 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
461 | // in a Construct, C/C++, predetermined, p.1] | |||
462 | // Variables appearing in threadprivate directives are threadprivate. | |||
463 | if (D->getTLSKind() != VarDecl::TLS_None || | |||
464 | (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() && | |||
465 | !D->isLocalVarDecl())) { | |||
466 | addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(), | |||
467 | D->getLocation()), | |||
468 | OMPC_threadprivate); | |||
469 | } | |||
470 | if (Stack[0].SharingMap.count(D)) { | |||
471 | DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; | |||
472 | DVar.CKind = OMPC_threadprivate; | |||
473 | return DVar; | |||
474 | } | |||
475 | ||||
476 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
477 | // in a Construct, C/C++, predetermined, p.1] | |||
478 | // Variables with automatic storage duration that are declared in a scope | |||
479 | // inside the construct are private. | |||
480 | OpenMPDirectiveKind Kind = | |||
481 | FromParent ? getParentDirective() : getCurrentDirective(); | |||
482 | auto StartI = std::next(Stack.rbegin()); | |||
483 | auto EndI = std::prev(Stack.rend()); | |||
484 | if (FromParent && StartI != EndI) { | |||
485 | StartI = std::next(StartI); | |||
486 | } | |||
487 | if (!isParallelOrTaskRegion(Kind)) { | |||
488 | if (isOpenMPLocal(D, StartI) && | |||
489 | ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto || | |||
490 | D->getStorageClass() == SC_None)) || | |||
491 | isa<ParmVarDecl>(D))) { | |||
492 | DVar.CKind = OMPC_private; | |||
493 | return DVar; | |||
494 | } | |||
495 | ||||
496 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
497 | // in a Construct, C/C++, predetermined, p.4] | |||
498 | // Static data members are shared. | |||
499 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
500 | // in a Construct, C/C++, predetermined, p.7] | |||
501 | // Variables with static storage duration that are declared in a scope | |||
502 | // inside the construct are shared. | |||
503 | if (D->isStaticDataMember() || D->isStaticLocal()) { | |||
504 | DSAVarData DVarTemp = | |||
505 | hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); | |||
506 | if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) | |||
507 | return DVar; | |||
508 | ||||
509 | DVar.CKind = OMPC_shared; | |||
510 | return DVar; | |||
511 | } | |||
512 | } | |||
513 | ||||
514 | QualType Type = D->getType().getNonReferenceType().getCanonicalType(); | |||
515 | bool IsConstant = Type.isConstant(SemaRef.getASTContext()); | |||
516 | Type = SemaRef.getASTContext().getBaseElementType(Type); | |||
517 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
518 | // in a Construct, C/C++, predetermined, p.6] | |||
519 | // Variables with const qualified type having no mutable member are | |||
520 | // shared. | |||
521 | CXXRecordDecl *RD = | |||
522 | SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; | |||
523 | if (IsConstant && | |||
524 | !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) { | |||
525 | // Variables with const-qualified type having no mutable member may be | |||
526 | // listed in a firstprivate clause, even if they are static data members. | |||
527 | DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), | |||
528 | MatchesAlways(), FromParent); | |||
529 | if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) | |||
530 | return DVar; | |||
531 | ||||
532 | DVar.CKind = OMPC_shared; | |||
533 | return DVar; | |||
534 | } | |||
535 | ||||
536 | // Explicitly specified attributes and local variables with predetermined | |||
537 | // attributes. | |||
538 | auto I = std::prev(StartI); | |||
539 | if (I->SharingMap.count(D)) { | |||
540 | DVar.RefExpr = I->SharingMap[D].RefExpr; | |||
541 | DVar.CKind = I->SharingMap[D].Attributes; | |||
542 | DVar.ImplicitDSALoc = I->DefaultAttrLoc; | |||
543 | } | |||
544 | ||||
545 | return DVar; | |||
546 | } | |||
547 | ||||
548 | DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) { | |||
549 | D = D->getCanonicalDecl(); | |||
550 | auto StartI = Stack.rbegin(); | |||
551 | auto EndI = std::prev(Stack.rend()); | |||
552 | if (FromParent && StartI != EndI) { | |||
553 | StartI = std::next(StartI); | |||
554 | } | |||
555 | return getDSA(StartI, D); | |||
556 | } | |||
557 | ||||
558 | template <class ClausesPredicate, class DirectivesPredicate> | |||
559 | DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred, | |||
560 | DirectivesPredicate DPred, | |||
561 | bool FromParent) { | |||
562 | D = D->getCanonicalDecl(); | |||
563 | auto StartI = std::next(Stack.rbegin()); | |||
564 | auto EndI = std::prev(Stack.rend()); | |||
565 | if (FromParent && StartI != EndI) { | |||
566 | StartI = std::next(StartI); | |||
567 | } | |||
568 | for (auto I = StartI, EE = EndI; I != EE; ++I) { | |||
569 | if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) | |||
570 | continue; | |||
571 | DSAVarData DVar = getDSA(I, D); | |||
572 | if (CPred(DVar.CKind)) | |||
573 | return DVar; | |||
574 | } | |||
575 | return DSAVarData(); | |||
576 | } | |||
577 | ||||
578 | template <class ClausesPredicate, class DirectivesPredicate> | |||
579 | DSAStackTy::DSAVarData | |||
580 | DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, | |||
581 | DirectivesPredicate DPred, bool FromParent) { | |||
582 | D = D->getCanonicalDecl(); | |||
583 | auto StartI = std::next(Stack.rbegin()); | |||
584 | auto EndI = std::prev(Stack.rend()); | |||
585 | if (FromParent && StartI != EndI) { | |||
586 | StartI = std::next(StartI); | |||
587 | } | |||
588 | for (auto I = StartI, EE = EndI; I != EE; ++I) { | |||
589 | if (!DPred(I->Directive)) | |||
590 | break; | |||
591 | DSAVarData DVar = getDSA(I, D); | |||
592 | if (CPred(DVar.CKind)) | |||
593 | return DVar; | |||
594 | return DSAVarData(); | |||
595 | } | |||
596 | return DSAVarData(); | |||
597 | } | |||
598 | ||||
599 | bool DSAStackTy::hasExplicitDSA( | |||
600 | VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, | |||
601 | unsigned Level) { | |||
602 | if (CPred(ClauseKindMode)) | |||
603 | return true; | |||
604 | if (isClauseParsingMode()) | |||
605 | ++Level; | |||
606 | D = D->getCanonicalDecl(); | |||
607 | auto StartI = Stack.rbegin(); | |||
608 | auto EndI = std::prev(Stack.rend()); | |||
609 | if (std::distance(StartI, EndI) <= (int)Level) | |||
610 | return false; | |||
611 | std::advance(StartI, Level); | |||
612 | return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr && | |||
613 | CPred(StartI->SharingMap[D].Attributes); | |||
614 | } | |||
615 | ||||
616 | template <class NamedDirectivesPredicate> | |||
617 | bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { | |||
618 | auto StartI = std::next(Stack.rbegin()); | |||
619 | auto EndI = std::prev(Stack.rend()); | |||
620 | if (FromParent && StartI != EndI) { | |||
621 | StartI = std::next(StartI); | |||
622 | } | |||
623 | for (auto I = StartI, EE = EndI; I != EE; ++I) { | |||
624 | if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) | |||
625 | return true; | |||
626 | } | |||
627 | return false; | |||
628 | } | |||
629 | ||||
630 | void Sema::InitDataSharingAttributesStack() { | |||
631 | VarDataSharingAttributesStack = new DSAStackTy(*this); | |||
632 | } | |||
633 | ||||
634 | #define DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ) static_cast<DSAStackTy *>(VarDataSharingAttributesStack) | |||
635 | ||||
636 | bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { | |||
637 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 637, __PRETTY_FUNCTION__)); | |||
638 | VD = VD->getCanonicalDecl(); | |||
639 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() != OMPD_unknown) { | |||
640 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isLoopControlVariable(VD) || | |||
641 | (VD->hasLocalStorage() && | |||
642 | isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()))) | |||
643 | return true; | |||
644 | auto DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | |||
645 | if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) | |||
646 | return true; | |||
647 | DVarPrivate = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), | |||
648 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isClauseParsingMode()); | |||
649 | return DVarPrivate.CKind != OMPC_unknown; | |||
650 | } | |||
651 | return false; | |||
652 | } | |||
653 | ||||
654 | bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) { | |||
655 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 655, __PRETTY_FUNCTION__)); | |||
656 | return DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasExplicitDSA( | |||
657 | VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); | |||
658 | } | |||
659 | ||||
660 | void Sema::DestroyDataSharingAttributesStack() { delete DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ); } | |||
661 | ||||
662 | void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, | |||
663 | const DeclarationNameInfo &DirName, | |||
664 | Scope *CurScope, SourceLocation Loc) { | |||
665 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->push(DKind, DirName, CurScope, Loc); | |||
666 | PushExpressionEvaluationContext(PotentiallyEvaluated); | |||
667 | } | |||
668 | ||||
669 | void Sema::StartOpenMPClause(OpenMPClauseKind K) { | |||
670 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(K); | |||
671 | } | |||
672 | ||||
673 | void Sema::EndOpenMPClause() { | |||
674 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setClauseParsingMode(/*K=*/OMPC_unknown); | |||
675 | } | |||
676 | ||||
677 | void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { | |||
678 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] | |||
679 | // A variable of class type (or array thereof) that appears in a lastprivate | |||
680 | // clause requires an accessible, unambiguous default constructor for the | |||
681 | // class type, unless the list item is also specified in a firstprivate | |||
682 | // clause. | |||
683 | if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { | |||
684 | for (auto *C : D->clauses()) { | |||
685 | if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { | |||
686 | SmallVector<Expr *, 8> PrivateCopies; | |||
687 | for (auto *DE : Clause->varlists()) { | |||
688 | if (DE->isValueDependent() || DE->isTypeDependent()) { | |||
689 | PrivateCopies.push_back(nullptr); | |||
690 | continue; | |||
691 | } | |||
692 | auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl()); | |||
693 | QualType Type = VD->getType(); | |||
694 | auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
695 | if (DVar.CKind == OMPC_lastprivate) { | |||
696 | // Generate helper private variable and initialize it with the | |||
697 | // default value. The address of the original variable is replaced | |||
698 | // by the address of the new private variable in CodeGen. This new | |||
699 | // variable is not added to IdResolver, so the code in the OpenMP | |||
700 | // region uses original variable for proper diagnostics. | |||
701 | auto *VDPrivate = | |||
702 | buildVarDecl(*this, DE->getExprLoc(), Type.getUnqualifiedType(), | |||
703 | VD->getName()); | |||
704 | ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); | |||
705 | if (VDPrivate->isInvalidDecl()) | |||
706 | continue; | |||
707 | PrivateCopies.push_back(buildDeclRefExpr( | |||
708 | *this, VDPrivate, DE->getType(), DE->getExprLoc())); | |||
709 | } else { | |||
710 | // The variable is also a firstprivate, so initialization sequence | |||
711 | // for private copy is generated already. | |||
712 | PrivateCopies.push_back(nullptr); | |||
713 | } | |||
714 | } | |||
715 | // Set initializers to private copies if no errors were found. | |||
716 | if (PrivateCopies.size() == Clause->varlist_size()) { | |||
717 | Clause->setPrivateCopies(PrivateCopies); | |||
718 | } | |||
719 | } | |||
720 | } | |||
721 | } | |||
722 | ||||
723 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->pop(); | |||
724 | DiscardCleanupsInEvaluationContext(); | |||
725 | PopExpressionEvaluationContext(); | |||
726 | } | |||
727 | ||||
728 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | |||
729 | Expr *NumIterations, Sema &SemaRef, | |||
730 | Scope *S); | |||
731 | ||||
732 | namespace { | |||
733 | ||||
734 | class VarDeclFilterCCC : public CorrectionCandidateCallback { | |||
735 | private: | |||
736 | Sema &SemaRef; | |||
737 | ||||
738 | public: | |||
739 | explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} | |||
740 | bool ValidateCandidate(const TypoCorrection &Candidate) override { | |||
741 | NamedDecl *ND = Candidate.getCorrectionDecl(); | |||
742 | if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { | |||
743 | return VD->hasGlobalStorage() && | |||
744 | SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), | |||
745 | SemaRef.getCurScope()); | |||
746 | } | |||
747 | return false; | |||
748 | } | |||
749 | }; | |||
750 | } // namespace | |||
751 | ||||
752 | ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, | |||
753 | CXXScopeSpec &ScopeSpec, | |||
754 | const DeclarationNameInfo &Id) { | |||
755 | LookupResult Lookup(*this, Id, LookupOrdinaryName); | |||
756 | LookupParsedName(Lookup, CurScope, &ScopeSpec, true); | |||
757 | ||||
758 | if (Lookup.isAmbiguous()) | |||
759 | return ExprError(); | |||
760 | ||||
761 | VarDecl *VD; | |||
762 | if (!Lookup.isSingleResult()) { | |||
763 | if (TypoCorrection Corrected = CorrectTypo( | |||
764 | Id, LookupOrdinaryName, CurScope, nullptr, | |||
765 | llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { | |||
766 | diagnoseTypo(Corrected, | |||
767 | PDiag(Lookup.empty() | |||
768 | ? diag::err_undeclared_var_use_suggest | |||
769 | : diag::err_omp_expected_var_arg_suggest) | |||
770 | << Id.getName()); | |||
771 | VD = Corrected.getCorrectionDeclAs<VarDecl>(); | |||
772 | } else { | |||
773 | Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use | |||
774 | : diag::err_omp_expected_var_arg) | |||
775 | << Id.getName(); | |||
776 | return ExprError(); | |||
777 | } | |||
778 | } else { | |||
779 | if (!(VD = Lookup.getAsSingle<VarDecl>())) { | |||
780 | Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); | |||
781 | Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); | |||
782 | return ExprError(); | |||
783 | } | |||
784 | } | |||
785 | Lookup.suppressDiagnostics(); | |||
786 | ||||
787 | // OpenMP [2.9.2, Syntax, C/C++] | |||
788 | // Variables must be file-scope, namespace-scope, or static block-scope. | |||
789 | if (!VD->hasGlobalStorage()) { | |||
790 | Diag(Id.getLoc(), diag::err_omp_global_var_arg) | |||
791 | << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); | |||
792 | bool IsDecl = | |||
793 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
794 | Diag(VD->getLocation(), | |||
795 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
796 | << VD; | |||
797 | return ExprError(); | |||
798 | } | |||
799 | ||||
800 | VarDecl *CanonicalVD = VD->getCanonicalDecl(); | |||
801 | NamedDecl *ND = cast<NamedDecl>(CanonicalVD); | |||
802 | // OpenMP [2.9.2, Restrictions, C/C++, p.2] | |||
803 | // A threadprivate directive for file-scope variables must appear outside | |||
804 | // any definition or declaration. | |||
805 | if (CanonicalVD->getDeclContext()->isTranslationUnit() && | |||
806 | !getCurLexicalContext()->isTranslationUnit()) { | |||
807 | Diag(Id.getLoc(), diag::err_omp_var_scope) | |||
808 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; | |||
809 | bool IsDecl = | |||
810 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
811 | Diag(VD->getLocation(), | |||
812 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
813 | << VD; | |||
814 | return ExprError(); | |||
815 | } | |||
816 | // OpenMP [2.9.2, Restrictions, C/C++, p.3] | |||
817 | // A threadprivate directive for static class member variables must appear | |||
818 | // in the class definition, in the same scope in which the member | |||
819 | // variables are declared. | |||
820 | if (CanonicalVD->isStaticDataMember() && | |||
821 | !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { | |||
822 | Diag(Id.getLoc(), diag::err_omp_var_scope) | |||
823 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; | |||
824 | bool IsDecl = | |||
825 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
826 | Diag(VD->getLocation(), | |||
827 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
828 | << VD; | |||
829 | return ExprError(); | |||
830 | } | |||
831 | // OpenMP [2.9.2, Restrictions, C/C++, p.4] | |||
832 | // A threadprivate directive for namespace-scope variables must appear | |||
833 | // outside any definition or declaration other than the namespace | |||
834 | // definition itself. | |||
835 | if (CanonicalVD->getDeclContext()->isNamespace() && | |||
836 | (!getCurLexicalContext()->isFileContext() || | |||
837 | !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { | |||
838 | Diag(Id.getLoc(), diag::err_omp_var_scope) | |||
839 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; | |||
840 | bool IsDecl = | |||
841 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
842 | Diag(VD->getLocation(), | |||
843 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
844 | << VD; | |||
845 | return ExprError(); | |||
846 | } | |||
847 | // OpenMP [2.9.2, Restrictions, C/C++, p.6] | |||
848 | // A threadprivate directive for static block-scope variables must appear | |||
849 | // in the scope of the variable and not in a nested scope. | |||
850 | if (CanonicalVD->isStaticLocal() && CurScope && | |||
851 | !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { | |||
852 | Diag(Id.getLoc(), diag::err_omp_var_scope) | |||
853 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; | |||
854 | bool IsDecl = | |||
855 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
856 | Diag(VD->getLocation(), | |||
857 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
858 | << VD; | |||
859 | return ExprError(); | |||
860 | } | |||
861 | ||||
862 | // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] | |||
863 | // A threadprivate directive must lexically precede all references to any | |||
864 | // of the variables in its list. | |||
865 | if (VD->isUsed() && !DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | |||
866 | Diag(Id.getLoc(), diag::err_omp_var_used) | |||
867 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD; | |||
868 | return ExprError(); | |||
869 | } | |||
870 | ||||
871 | QualType ExprType = VD->getType().getNonReferenceType(); | |||
872 | ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc()); | |||
873 | return DE; | |||
874 | } | |||
875 | ||||
876 | Sema::DeclGroupPtrTy | |||
877 | Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, | |||
878 | ArrayRef<Expr *> VarList) { | |||
879 | if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { | |||
880 | CurContext->addDecl(D); | |||
881 | return DeclGroupPtrTy::make(DeclGroupRef(D)); | |||
882 | } | |||
883 | return DeclGroupPtrTy(); | |||
884 | } | |||
885 | ||||
886 | namespace { | |||
887 | class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { | |||
888 | Sema &SemaRef; | |||
889 | ||||
890 | public: | |||
891 | bool VisitDeclRefExpr(const DeclRefExpr *E) { | |||
892 | if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { | |||
893 | if (VD->hasLocalStorage()) { | |||
894 | SemaRef.Diag(E->getLocStart(), | |||
895 | diag::err_omp_local_var_in_threadprivate_init) | |||
896 | << E->getSourceRange(); | |||
897 | SemaRef.Diag(VD->getLocation(), diag::note_defined_here) | |||
898 | << VD << VD->getSourceRange(); | |||
899 | return true; | |||
900 | } | |||
901 | } | |||
902 | return false; | |||
903 | } | |||
904 | bool VisitStmt(const Stmt *S) { | |||
905 | for (auto Child : S->children()) { | |||
906 | if (Child && Visit(Child)) | |||
907 | return true; | |||
908 | } | |||
909 | return false; | |||
910 | } | |||
911 | explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} | |||
912 | }; | |||
913 | } // namespace | |||
914 | ||||
915 | OMPThreadPrivateDecl * | |||
916 | Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { | |||
917 | SmallVector<Expr *, 8> Vars; | |||
918 | for (auto &RefExpr : VarList) { | |||
919 | DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); | |||
920 | VarDecl *VD = cast<VarDecl>(DE->getDecl()); | |||
921 | SourceLocation ILoc = DE->getExprLoc(); | |||
922 | ||||
923 | QualType QType = VD->getType(); | |||
924 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { | |||
925 | // It will be analyzed later. | |||
926 | Vars.push_back(DE); | |||
927 | continue; | |||
928 | } | |||
929 | ||||
930 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | |||
931 | // A threadprivate variable must not have an incomplete type. | |||
932 | if (RequireCompleteType(ILoc, VD->getType(), | |||
933 | diag::err_omp_threadprivate_incomplete_type)) { | |||
934 | continue; | |||
935 | } | |||
936 | ||||
937 | // OpenMP [2.9.2, Restrictions, C/C++, p.10] | |||
938 | // A threadprivate variable must not have a reference type. | |||
939 | if (VD->getType()->isReferenceType()) { | |||
940 | Diag(ILoc, diag::err_omp_ref_type_arg) | |||
941 | << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); | |||
942 | bool IsDecl = | |||
943 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
944 | Diag(VD->getLocation(), | |||
945 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
946 | << VD; | |||
947 | continue; | |||
948 | } | |||
949 | ||||
950 | // Check if this is a TLS variable. | |||
951 | if (VD->getTLSKind() != VarDecl::TLS_None || | |||
952 | (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && | |||
953 | !VD->isLocalVarDecl())) { | |||
954 | Diag(ILoc, diag::err_omp_var_thread_local) | |||
955 | << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); | |||
956 | bool IsDecl = | |||
957 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
958 | Diag(VD->getLocation(), | |||
959 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
960 | << VD; | |||
961 | continue; | |||
962 | } | |||
963 | ||||
964 | // Check if initial value of threadprivate variable reference variable with | |||
965 | // local storage (it is not supported by runtime). | |||
966 | if (auto Init = VD->getAnyInitializer()) { | |||
967 | LocalVarRefChecker Checker(*this); | |||
968 | if (Checker.Visit(Init)) | |||
969 | continue; | |||
970 | } | |||
971 | ||||
972 | Vars.push_back(RefExpr); | |||
973 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_threadprivate); | |||
974 | VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( | |||
975 | Context, SourceRange(Loc, Loc))); | |||
976 | if (auto *ML = Context.getASTMutationListener()) | |||
977 | ML->DeclarationMarkedOpenMPThreadPrivate(VD); | |||
978 | } | |||
979 | OMPThreadPrivateDecl *D = nullptr; | |||
980 | if (!Vars.empty()) { | |||
981 | D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, | |||
982 | Vars); | |||
983 | D->setAccess(AS_public); | |||
984 | } | |||
985 | return D; | |||
986 | } | |||
987 | ||||
988 | static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, | |||
989 | const VarDecl *VD, DSAStackTy::DSAVarData DVar, | |||
990 | bool IsLoopIterVar = false) { | |||
991 | if (DVar.RefExpr) { | |||
992 | SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) | |||
993 | << getOpenMPClauseName(DVar.CKind); | |||
994 | return; | |||
995 | } | |||
996 | enum { | |||
997 | PDSA_StaticMemberShared, | |||
998 | PDSA_StaticLocalVarShared, | |||
999 | PDSA_LoopIterVarPrivate, | |||
1000 | PDSA_LoopIterVarLinear, | |||
1001 | PDSA_LoopIterVarLastprivate, | |||
1002 | PDSA_ConstVarShared, | |||
1003 | PDSA_GlobalVarShared, | |||
1004 | PDSA_TaskVarFirstprivate, | |||
1005 | PDSA_LocalVarPrivate, | |||
1006 | PDSA_Implicit | |||
1007 | } Reason = PDSA_Implicit; | |||
1008 | bool ReportHint = false; | |||
1009 | auto ReportLoc = VD->getLocation(); | |||
1010 | if (IsLoopIterVar) { | |||
1011 | if (DVar.CKind == OMPC_private) | |||
1012 | Reason = PDSA_LoopIterVarPrivate; | |||
1013 | else if (DVar.CKind == OMPC_lastprivate) | |||
1014 | Reason = PDSA_LoopIterVarLastprivate; | |||
1015 | else | |||
1016 | Reason = PDSA_LoopIterVarLinear; | |||
1017 | } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { | |||
1018 | Reason = PDSA_TaskVarFirstprivate; | |||
1019 | ReportLoc = DVar.ImplicitDSALoc; | |||
1020 | } else if (VD->isStaticLocal()) | |||
1021 | Reason = PDSA_StaticLocalVarShared; | |||
1022 | else if (VD->isStaticDataMember()) | |||
1023 | Reason = PDSA_StaticMemberShared; | |||
1024 | else if (VD->isFileVarDecl()) | |||
1025 | Reason = PDSA_GlobalVarShared; | |||
1026 | else if (VD->getType().isConstant(SemaRef.getASTContext())) | |||
1027 | Reason = PDSA_ConstVarShared; | |||
1028 | else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { | |||
1029 | ReportHint = true; | |||
1030 | Reason = PDSA_LocalVarPrivate; | |||
1031 | } | |||
1032 | if (Reason != PDSA_Implicit) { | |||
1033 | SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) | |||
1034 | << Reason << ReportHint | |||
1035 | << getOpenMPDirectiveName(Stack->getCurrentDirective()); | |||
1036 | } else if (DVar.ImplicitDSALoc.isValid()) { | |||
1037 | SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) | |||
1038 | << getOpenMPClauseName(DVar.CKind); | |||
1039 | } | |||
1040 | } | |||
1041 | ||||
1042 | namespace { | |||
1043 | class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { | |||
1044 | DSAStackTy *Stack; | |||
1045 | Sema &SemaRef; | |||
1046 | bool ErrorFound; | |||
1047 | CapturedStmt *CS; | |||
1048 | llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; | |||
1049 | llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; | |||
1050 | ||||
1051 | public: | |||
1052 | void VisitDeclRefExpr(DeclRefExpr *E) { | |||
1053 | if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { | |||
1054 | // Skip internally declared variables. | |||
1055 | if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) | |||
1056 | return; | |||
1057 | ||||
1058 | auto DVar = Stack->getTopDSA(VD, false); | |||
1059 | // Check if the variable has explicit DSA set and stop analysis if it so. | |||
1060 | if (DVar.RefExpr) return; | |||
1061 | ||||
1062 | auto ELoc = E->getExprLoc(); | |||
1063 | auto DKind = Stack->getCurrentDirective(); | |||
1064 | // The default(none) clause requires that each variable that is referenced | |||
1065 | // in the construct, and does not have a predetermined data-sharing | |||
1066 | // attribute, must have its data-sharing attribute explicitly determined | |||
1067 | // by being listed in a data-sharing attribute clause. | |||
1068 | if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && | |||
1069 | isParallelOrTaskRegion(DKind) && | |||
1070 | VarsWithInheritedDSA.count(VD) == 0) { | |||
1071 | VarsWithInheritedDSA[VD] = E; | |||
1072 | return; | |||
1073 | } | |||
1074 | ||||
1075 | // OpenMP [2.9.3.6, Restrictions, p.2] | |||
1076 | // A list item that appears in a reduction clause of the innermost | |||
1077 | // enclosing worksharing or parallel construct may not be accessed in an | |||
1078 | // explicit task. | |||
1079 | DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), | |||
1080 | [](OpenMPDirectiveKind K) -> bool { | |||
1081 | return isOpenMPParallelDirective(K) || | |||
1082 | isOpenMPWorksharingDirective(K) || | |||
1083 | isOpenMPTeamsDirective(K); | |||
1084 | }, | |||
1085 | false); | |||
1086 | if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { | |||
1087 | ErrorFound = true; | |||
1088 | SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); | |||
1089 | ReportOriginalDSA(SemaRef, Stack, VD, DVar); | |||
1090 | return; | |||
1091 | } | |||
1092 | ||||
1093 | // Define implicit data-sharing attributes for task. | |||
1094 | DVar = Stack->getImplicitDSA(VD, false); | |||
1095 | if (DKind == OMPD_task && DVar.CKind != OMPC_shared) | |||
1096 | ImplicitFirstprivate.push_back(E); | |||
1097 | } | |||
1098 | } | |||
1099 | void VisitOMPExecutableDirective(OMPExecutableDirective *S) { | |||
1100 | for (auto *C : S->clauses()) { | |||
1101 | // Skip analysis of arguments of implicitly defined firstprivate clause | |||
1102 | // for task directives. | |||
1103 | if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) | |||
1104 | for (auto *CC : C->children()) { | |||
1105 | if (CC) | |||
1106 | Visit(CC); | |||
1107 | } | |||
1108 | } | |||
1109 | } | |||
1110 | void VisitStmt(Stmt *S) { | |||
1111 | for (auto *C : S->children()) { | |||
1112 | if (C && !isa<OMPExecutableDirective>(C)) | |||
1113 | Visit(C); | |||
1114 | } | |||
1115 | } | |||
1116 | ||||
1117 | bool isErrorFound() { return ErrorFound; } | |||
1118 | ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } | |||
1119 | llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() { | |||
1120 | return VarsWithInheritedDSA; | |||
1121 | } | |||
1122 | ||||
1123 | DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) | |||
1124 | : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} | |||
1125 | }; | |||
1126 | } // namespace | |||
1127 | ||||
1128 | void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { | |||
1129 | switch (DKind) { | |||
1130 | case OMPD_parallel: { | |||
1131 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1132 | QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); | |||
1133 | Sema::CapturedParamNameType Params[] = { | |||
1134 | std::make_pair(".global_tid.", KmpInt32PtrTy), | |||
1135 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | |||
1136 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1137 | }; | |||
1138 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1139 | Params); | |||
1140 | break; | |||
1141 | } | |||
1142 | case OMPD_simd: { | |||
1143 | Sema::CapturedParamNameType Params[] = { | |||
1144 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1145 | }; | |||
1146 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1147 | Params); | |||
1148 | break; | |||
1149 | } | |||
1150 | case OMPD_for: { | |||
1151 | Sema::CapturedParamNameType Params[] = { | |||
1152 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1153 | }; | |||
1154 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1155 | Params); | |||
1156 | break; | |||
1157 | } | |||
1158 | case OMPD_for_simd: { | |||
1159 | Sema::CapturedParamNameType Params[] = { | |||
1160 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1161 | }; | |||
1162 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1163 | Params); | |||
1164 | break; | |||
1165 | } | |||
1166 | case OMPD_sections: { | |||
1167 | Sema::CapturedParamNameType Params[] = { | |||
1168 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1169 | }; | |||
1170 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1171 | Params); | |||
1172 | break; | |||
1173 | } | |||
1174 | case OMPD_section: { | |||
1175 | Sema::CapturedParamNameType Params[] = { | |||
1176 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1177 | }; | |||
1178 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1179 | Params); | |||
1180 | break; | |||
1181 | } | |||
1182 | case OMPD_single: { | |||
1183 | Sema::CapturedParamNameType Params[] = { | |||
1184 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1185 | }; | |||
1186 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1187 | Params); | |||
1188 | break; | |||
1189 | } | |||
1190 | case OMPD_master: { | |||
1191 | Sema::CapturedParamNameType Params[] = { | |||
1192 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1193 | }; | |||
1194 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1195 | Params); | |||
1196 | break; | |||
1197 | } | |||
1198 | case OMPD_critical: { | |||
1199 | Sema::CapturedParamNameType Params[] = { | |||
1200 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1201 | }; | |||
1202 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1203 | Params); | |||
1204 | break; | |||
1205 | } | |||
1206 | case OMPD_parallel_for: { | |||
1207 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1208 | QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); | |||
1209 | Sema::CapturedParamNameType Params[] = { | |||
1210 | std::make_pair(".global_tid.", KmpInt32PtrTy), | |||
1211 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | |||
1212 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1213 | }; | |||
1214 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1215 | Params); | |||
1216 | break; | |||
1217 | } | |||
1218 | case OMPD_parallel_for_simd: { | |||
1219 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1220 | QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); | |||
1221 | Sema::CapturedParamNameType Params[] = { | |||
1222 | std::make_pair(".global_tid.", KmpInt32PtrTy), | |||
1223 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | |||
1224 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1225 | }; | |||
1226 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1227 | Params); | |||
1228 | break; | |||
1229 | } | |||
1230 | case OMPD_parallel_sections: { | |||
1231 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1232 | QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); | |||
1233 | Sema::CapturedParamNameType Params[] = { | |||
1234 | std::make_pair(".global_tid.", KmpInt32PtrTy), | |||
1235 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | |||
1236 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1237 | }; | |||
1238 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1239 | Params); | |||
1240 | break; | |||
1241 | } | |||
1242 | case OMPD_task: { | |||
1243 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1244 | QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; | |||
1245 | FunctionProtoType::ExtProtoInfo EPI; | |||
1246 | EPI.Variadic = true; | |||
1247 | QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); | |||
1248 | Sema::CapturedParamNameType Params[] = { | |||
1249 | std::make_pair(".global_tid.", KmpInt32Ty), | |||
1250 | std::make_pair(".part_id.", KmpInt32Ty), | |||
1251 | std::make_pair(".privates.", | |||
1252 | Context.VoidPtrTy.withConst().withRestrict()), | |||
1253 | std::make_pair( | |||
1254 | ".copy_fn.", | |||
1255 | Context.getPointerType(CopyFnType).withConst().withRestrict()), | |||
1256 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1257 | }; | |||
1258 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1259 | Params); | |||
1260 | // Mark this captured region as inlined, because we don't use outlined | |||
1261 | // function directly. | |||
1262 | getCurCapturedRegion()->TheCapturedDecl->addAttr( | |||
1263 | AlwaysInlineAttr::CreateImplicit( | |||
1264 | Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); | |||
1265 | break; | |||
1266 | } | |||
1267 | case OMPD_ordered: { | |||
1268 | Sema::CapturedParamNameType Params[] = { | |||
1269 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1270 | }; | |||
1271 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1272 | Params); | |||
1273 | break; | |||
1274 | } | |||
1275 | case OMPD_atomic: { | |||
1276 | Sema::CapturedParamNameType Params[] = { | |||
1277 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1278 | }; | |||
1279 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1280 | Params); | |||
1281 | break; | |||
1282 | } | |||
1283 | case OMPD_target: { | |||
1284 | Sema::CapturedParamNameType Params[] = { | |||
1285 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1286 | }; | |||
1287 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1288 | Params); | |||
1289 | break; | |||
1290 | } | |||
1291 | case OMPD_teams: { | |||
1292 | QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); | |||
1293 | QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); | |||
1294 | Sema::CapturedParamNameType Params[] = { | |||
1295 | std::make_pair(".global_tid.", KmpInt32PtrTy), | |||
1296 | std::make_pair(".bound_tid.", KmpInt32PtrTy), | |||
1297 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1298 | }; | |||
1299 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1300 | Params); | |||
1301 | break; | |||
1302 | } | |||
1303 | case OMPD_taskgroup: { | |||
1304 | Sema::CapturedParamNameType Params[] = { | |||
1305 | std::make_pair(StringRef(), QualType()) // __context with shared vars | |||
1306 | }; | |||
1307 | ActOnCapturedRegionStart(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(), CurScope, CR_OpenMP, | |||
1308 | Params); | |||
1309 | break; | |||
1310 | } | |||
1311 | case OMPD_threadprivate: | |||
1312 | case OMPD_taskyield: | |||
1313 | case OMPD_barrier: | |||
1314 | case OMPD_taskwait: | |||
1315 | case OMPD_flush: | |||
1316 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1316); | |||
1317 | case OMPD_unknown: | |||
1318 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1318); | |||
1319 | } | |||
1320 | } | |||
1321 | ||||
1322 | StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, | |||
1323 | ArrayRef<OMPClause *> Clauses) { | |||
1324 | if (!S.isUsable()) { | |||
1325 | ActOnCapturedRegionError(); | |||
1326 | return StmtError(); | |||
1327 | } | |||
1328 | // This is required for proper codegen. | |||
1329 | for (auto *Clause : Clauses) { | |||
1330 | if (isOpenMPPrivate(Clause->getClauseKind()) || | |||
1331 | Clause->getClauseKind() == OMPC_copyprivate) { | |||
1332 | // Mark all variables in private list clauses as used in inner region. | |||
1333 | for (auto *VarRef : Clause->children()) { | |||
1334 | if (auto *E = cast_or_null<Expr>(VarRef)) { | |||
1335 | MarkDeclarationsReferencedInExpr(E); | |||
1336 | } | |||
1337 | } | |||
1338 | } else if (isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()) && | |||
1339 | Clause->getClauseKind() == OMPC_schedule) { | |||
1340 | // Mark all variables in private list clauses as used in inner region. | |||
1341 | // Required for proper codegen of combined directives. | |||
1342 | // TODO: add processing for other clauses. | |||
1343 | if (auto *E = cast_or_null<Expr>( | |||
1344 | cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) { | |||
1345 | MarkDeclarationsReferencedInExpr(E); | |||
1346 | } | |||
1347 | } | |||
1348 | } | |||
1349 | return ActOnCapturedRegionEnd(S.get()); | |||
1350 | } | |||
1351 | ||||
1352 | static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, | |||
1353 | OpenMPDirectiveKind CurrentRegion, | |||
1354 | const DeclarationNameInfo &CurrentName, | |||
1355 | SourceLocation StartLoc) { | |||
1356 | // Allowed nesting of constructs | |||
1357 | // +------------------+-----------------+------------------------------------+ | |||
1358 | // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| | |||
1359 | // +------------------+-----------------+------------------------------------+ | |||
1360 | // | parallel | parallel | * | | |||
1361 | // | parallel | for | * | | |||
1362 | // | parallel | for simd | * | | |||
1363 | // | parallel | master | * | | |||
1364 | // | parallel | critical | * | | |||
1365 | // | parallel | simd | * | | |||
1366 | // | parallel | sections | * | | |||
1367 | // | parallel | section | + | | |||
1368 | // | parallel | single | * | | |||
1369 | // | parallel | parallel for | * | | |||
1370 | // | parallel |parallel for simd| * | | |||
1371 | // | parallel |parallel sections| * | | |||
1372 | // | parallel | task | * | | |||
1373 | // | parallel | taskyield | * | | |||
1374 | // | parallel | barrier | * | | |||
1375 | // | parallel | taskwait | * | | |||
1376 | // | parallel | taskgroup | * | | |||
1377 | // | parallel | flush | * | | |||
1378 | // | parallel | ordered | + | | |||
1379 | // | parallel | atomic | * | | |||
1380 | // | parallel | target | * | | |||
1381 | // | parallel | teams | + | | |||
1382 | // +------------------+-----------------+------------------------------------+ | |||
1383 | // | for | parallel | * | | |||
1384 | // | for | for | + | | |||
1385 | // | for | for simd | + | | |||
1386 | // | for | master | + | | |||
1387 | // | for | critical | * | | |||
1388 | // | for | simd | * | | |||
1389 | // | for | sections | + | | |||
1390 | // | for | section | + | | |||
1391 | // | for | single | + | | |||
1392 | // | for | parallel for | * | | |||
1393 | // | for |parallel for simd| * | | |||
1394 | // | for |parallel sections| * | | |||
1395 | // | for | task | * | | |||
1396 | // | for | taskyield | * | | |||
1397 | // | for | barrier | + | | |||
1398 | // | for | taskwait | * | | |||
1399 | // | for | taskgroup | * | | |||
1400 | // | for | flush | * | | |||
1401 | // | for | ordered | * (if construct is ordered) | | |||
1402 | // | for | atomic | * | | |||
1403 | // | for | target | * | | |||
1404 | // | for | teams | + | | |||
1405 | // +------------------+-----------------+------------------------------------+ | |||
1406 | // | master | parallel | * | | |||
1407 | // | master | for | + | | |||
1408 | // | master | for simd | + | | |||
1409 | // | master | master | * | | |||
1410 | // | master | critical | * | | |||
1411 | // | master | simd | * | | |||
1412 | // | master | sections | + | | |||
1413 | // | master | section | + | | |||
1414 | // | master | single | + | | |||
1415 | // | master | parallel for | * | | |||
1416 | // | master |parallel for simd| * | | |||
1417 | // | master |parallel sections| * | | |||
1418 | // | master | task | * | | |||
1419 | // | master | taskyield | * | | |||
1420 | // | master | barrier | + | | |||
1421 | // | master | taskwait | * | | |||
1422 | // | master | taskgroup | * | | |||
1423 | // | master | flush | * | | |||
1424 | // | master | ordered | + | | |||
1425 | // | master | atomic | * | | |||
1426 | // | master | target | * | | |||
1427 | // | master | teams | + | | |||
1428 | // +------------------+-----------------+------------------------------------+ | |||
1429 | // | critical | parallel | * | | |||
1430 | // | critical | for | + | | |||
1431 | // | critical | for simd | + | | |||
1432 | // | critical | master | * | | |||
1433 | // | critical | critical | * (should have different names) | | |||
1434 | // | critical | simd | * | | |||
1435 | // | critical | sections | + | | |||
1436 | // | critical | section | + | | |||
1437 | // | critical | single | + | | |||
1438 | // | critical | parallel for | * | | |||
1439 | // | critical |parallel for simd| * | | |||
1440 | // | critical |parallel sections| * | | |||
1441 | // | critical | task | * | | |||
1442 | // | critical | taskyield | * | | |||
1443 | // | critical | barrier | + | | |||
1444 | // | critical | taskwait | * | | |||
1445 | // | critical | taskgroup | * | | |||
1446 | // | critical | ordered | + | | |||
1447 | // | critical | atomic | * | | |||
1448 | // | critical | target | * | | |||
1449 | // | critical | teams | + | | |||
1450 | // +------------------+-----------------+------------------------------------+ | |||
1451 | // | simd | parallel | | | |||
1452 | // | simd | for | | | |||
1453 | // | simd | for simd | | | |||
1454 | // | simd | master | | | |||
1455 | // | simd | critical | | | |||
1456 | // | simd | simd | | | |||
1457 | // | simd | sections | | | |||
1458 | // | simd | section | | | |||
1459 | // | simd | single | | | |||
1460 | // | simd | parallel for | | | |||
1461 | // | simd |parallel for simd| | | |||
1462 | // | simd |parallel sections| | | |||
1463 | // | simd | task | | | |||
1464 | // | simd | taskyield | | | |||
1465 | // | simd | barrier | | | |||
1466 | // | simd | taskwait | | | |||
1467 | // | simd | taskgroup | | | |||
1468 | // | simd | flush | | | |||
1469 | // | simd | ordered | | | |||
1470 | // | simd | atomic | | | |||
1471 | // | simd | target | | | |||
1472 | // | simd | teams | | | |||
1473 | // +------------------+-----------------+------------------------------------+ | |||
1474 | // | for simd | parallel | | | |||
1475 | // | for simd | for | | | |||
1476 | // | for simd | for simd | | | |||
1477 | // | for simd | master | | | |||
1478 | // | for simd | critical | | | |||
1479 | // | for simd | simd | | | |||
1480 | // | for simd | sections | | | |||
1481 | // | for simd | section | | | |||
1482 | // | for simd | single | | | |||
1483 | // | for simd | parallel for | | | |||
1484 | // | for simd |parallel for simd| | | |||
1485 | // | for simd |parallel sections| | | |||
1486 | // | for simd | task | | | |||
1487 | // | for simd | taskyield | | | |||
1488 | // | for simd | barrier | | | |||
1489 | // | for simd | taskwait | | | |||
1490 | // | for simd | taskgroup | | | |||
1491 | // | for simd | flush | | | |||
1492 | // | for simd | ordered | | | |||
1493 | // | for simd | atomic | | | |||
1494 | // | for simd | target | | | |||
1495 | // | for simd | teams | | | |||
1496 | // +------------------+-----------------+------------------------------------+ | |||
1497 | // | parallel for simd| parallel | | | |||
1498 | // | parallel for simd| for | | | |||
1499 | // | parallel for simd| for simd | | | |||
1500 | // | parallel for simd| master | | | |||
1501 | // | parallel for simd| critical | | | |||
1502 | // | parallel for simd| simd | | | |||
1503 | // | parallel for simd| sections | | | |||
1504 | // | parallel for simd| section | | | |||
1505 | // | parallel for simd| single | | | |||
1506 | // | parallel for simd| parallel for | | | |||
1507 | // | parallel for simd|parallel for simd| | | |||
1508 | // | parallel for simd|parallel sections| | | |||
1509 | // | parallel for simd| task | | | |||
1510 | // | parallel for simd| taskyield | | | |||
1511 | // | parallel for simd| barrier | | | |||
1512 | // | parallel for simd| taskwait | | | |||
1513 | // | parallel for simd| taskgroup | | | |||
1514 | // | parallel for simd| flush | | | |||
1515 | // | parallel for simd| ordered | | | |||
1516 | // | parallel for simd| atomic | | | |||
1517 | // | parallel for simd| target | | | |||
1518 | // | parallel for simd| teams | | | |||
1519 | // +------------------+-----------------+------------------------------------+ | |||
1520 | // | sections | parallel | * | | |||
1521 | // | sections | for | + | | |||
1522 | // | sections | for simd | + | | |||
1523 | // | sections | master | + | | |||
1524 | // | sections | critical | * | | |||
1525 | // | sections | simd | * | | |||
1526 | // | sections | sections | + | | |||
1527 | // | sections | section | * | | |||
1528 | // | sections | single | + | | |||
1529 | // | sections | parallel for | * | | |||
1530 | // | sections |parallel for simd| * | | |||
1531 | // | sections |parallel sections| * | | |||
1532 | // | sections | task | * | | |||
1533 | // | sections | taskyield | * | | |||
1534 | // | sections | barrier | + | | |||
1535 | // | sections | taskwait | * | | |||
1536 | // | sections | taskgroup | * | | |||
1537 | // | sections | flush | * | | |||
1538 | // | sections | ordered | + | | |||
1539 | // | sections | atomic | * | | |||
1540 | // | sections | target | * | | |||
1541 | // | sections | teams | + | | |||
1542 | // +------------------+-----------------+------------------------------------+ | |||
1543 | // | section | parallel | * | | |||
1544 | // | section | for | + | | |||
1545 | // | section | for simd | + | | |||
1546 | // | section | master | + | | |||
1547 | // | section | critical | * | | |||
1548 | // | section | simd | * | | |||
1549 | // | section | sections | + | | |||
1550 | // | section | section | + | | |||
1551 | // | section | single | + | | |||
1552 | // | section | parallel for | * | | |||
1553 | // | section |parallel for simd| * | | |||
1554 | // | section |parallel sections| * | | |||
1555 | // | section | task | * | | |||
1556 | // | section | taskyield | * | | |||
1557 | // | section | barrier | + | | |||
1558 | // | section | taskwait | * | | |||
1559 | // | section | taskgroup | * | | |||
1560 | // | section | flush | * | | |||
1561 | // | section | ordered | + | | |||
1562 | // | section | atomic | * | | |||
1563 | // | section | target | * | | |||
1564 | // | section | teams | + | | |||
1565 | // +------------------+-----------------+------------------------------------+ | |||
1566 | // | single | parallel | * | | |||
1567 | // | single | for | + | | |||
1568 | // | single | for simd | + | | |||
1569 | // | single | master | + | | |||
1570 | // | single | critical | * | | |||
1571 | // | single | simd | * | | |||
1572 | // | single | sections | + | | |||
1573 | // | single | section | + | | |||
1574 | // | single | single | + | | |||
1575 | // | single | parallel for | * | | |||
1576 | // | single |parallel for simd| * | | |||
1577 | // | single |parallel sections| * | | |||
1578 | // | single | task | * | | |||
1579 | // | single | taskyield | * | | |||
1580 | // | single | barrier | + | | |||
1581 | // | single | taskwait | * | | |||
1582 | // | single | taskgroup | * | | |||
1583 | // | single | flush | * | | |||
1584 | // | single | ordered | + | | |||
1585 | // | single | atomic | * | | |||
1586 | // | single | target | * | | |||
1587 | // | single | teams | + | | |||
1588 | // +------------------+-----------------+------------------------------------+ | |||
1589 | // | parallel for | parallel | * | | |||
1590 | // | parallel for | for | + | | |||
1591 | // | parallel for | for simd | + | | |||
1592 | // | parallel for | master | + | | |||
1593 | // | parallel for | critical | * | | |||
1594 | // | parallel for | simd | * | | |||
1595 | // | parallel for | sections | + | | |||
1596 | // | parallel for | section | + | | |||
1597 | // | parallel for | single | + | | |||
1598 | // | parallel for | parallel for | * | | |||
1599 | // | parallel for |parallel for simd| * | | |||
1600 | // | parallel for |parallel sections| * | | |||
1601 | // | parallel for | task | * | | |||
1602 | // | parallel for | taskyield | * | | |||
1603 | // | parallel for | barrier | + | | |||
1604 | // | parallel for | taskwait | * | | |||
1605 | // | parallel for | taskgroup | * | | |||
1606 | // | parallel for | flush | * | | |||
1607 | // | parallel for | ordered | * (if construct is ordered) | | |||
1608 | // | parallel for | atomic | * | | |||
1609 | // | parallel for | target | * | | |||
1610 | // | parallel for | teams | + | | |||
1611 | // +------------------+-----------------+------------------------------------+ | |||
1612 | // | parallel sections| parallel | * | | |||
1613 | // | parallel sections| for | + | | |||
1614 | // | parallel sections| for simd | + | | |||
1615 | // | parallel sections| master | + | | |||
1616 | // | parallel sections| critical | + | | |||
1617 | // | parallel sections| simd | * | | |||
1618 | // | parallel sections| sections | + | | |||
1619 | // | parallel sections| section | * | | |||
1620 | // | parallel sections| single | + | | |||
1621 | // | parallel sections| parallel for | * | | |||
1622 | // | parallel sections|parallel for simd| * | | |||
1623 | // | parallel sections|parallel sections| * | | |||
1624 | // | parallel sections| task | * | | |||
1625 | // | parallel sections| taskyield | * | | |||
1626 | // | parallel sections| barrier | + | | |||
1627 | // | parallel sections| taskwait | * | | |||
1628 | // | parallel sections| taskgroup | * | | |||
1629 | // | parallel sections| flush | * | | |||
1630 | // | parallel sections| ordered | + | | |||
1631 | // | parallel sections| atomic | * | | |||
1632 | // | parallel sections| target | * | | |||
1633 | // | parallel sections| teams | + | | |||
1634 | // +------------------+-----------------+------------------------------------+ | |||
1635 | // | task | parallel | * | | |||
1636 | // | task | for | + | | |||
1637 | // | task | for simd | + | | |||
1638 | // | task | master | + | | |||
1639 | // | task | critical | * | | |||
1640 | // | task | simd | * | | |||
1641 | // | task | sections | + | | |||
1642 | // | task | section | + | | |||
1643 | // | task | single | + | | |||
1644 | // | task | parallel for | * | | |||
1645 | // | task |parallel for simd| * | | |||
1646 | // | task |parallel sections| * | | |||
1647 | // | task | task | * | | |||
1648 | // | task | taskyield | * | | |||
1649 | // | task | barrier | + | | |||
1650 | // | task | taskwait | * | | |||
1651 | // | task | taskgroup | * | | |||
1652 | // | task | flush | * | | |||
1653 | // | task | ordered | + | | |||
1654 | // | task | atomic | * | | |||
1655 | // | task | target | * | | |||
1656 | // | task | teams | + | | |||
1657 | // +------------------+-----------------+------------------------------------+ | |||
1658 | // | ordered | parallel | * | | |||
1659 | // | ordered | for | + | | |||
1660 | // | ordered | for simd | + | | |||
1661 | // | ordered | master | * | | |||
1662 | // | ordered | critical | * | | |||
1663 | // | ordered | simd | * | | |||
1664 | // | ordered | sections | + | | |||
1665 | // | ordered | section | + | | |||
1666 | // | ordered | single | + | | |||
1667 | // | ordered | parallel for | * | | |||
1668 | // | ordered |parallel for simd| * | | |||
1669 | // | ordered |parallel sections| * | | |||
1670 | // | ordered | task | * | | |||
1671 | // | ordered | taskyield | * | | |||
1672 | // | ordered | barrier | + | | |||
1673 | // | ordered | taskwait | * | | |||
1674 | // | ordered | taskgroup | * | | |||
1675 | // | ordered | flush | * | | |||
1676 | // | ordered | ordered | + | | |||
1677 | // | ordered | atomic | * | | |||
1678 | // | ordered | target | * | | |||
1679 | // | ordered | teams | + | | |||
1680 | // +------------------+-----------------+------------------------------------+ | |||
1681 | // | atomic | parallel | | | |||
1682 | // | atomic | for | | | |||
1683 | // | atomic | for simd | | | |||
1684 | // | atomic | master | | | |||
1685 | // | atomic | critical | | | |||
1686 | // | atomic | simd | | | |||
1687 | // | atomic | sections | | | |||
1688 | // | atomic | section | | | |||
1689 | // | atomic | single | | | |||
1690 | // | atomic | parallel for | | | |||
1691 | // | atomic |parallel for simd| | | |||
1692 | // | atomic |parallel sections| | | |||
1693 | // | atomic | task | | | |||
1694 | // | atomic | taskyield | | | |||
1695 | // | atomic | barrier | | | |||
1696 | // | atomic | taskwait | | | |||
1697 | // | atomic | taskgroup | | | |||
1698 | // | atomic | flush | | | |||
1699 | // | atomic | ordered | | | |||
1700 | // | atomic | atomic | | | |||
1701 | // | atomic | target | | | |||
1702 | // | atomic | teams | | | |||
1703 | // +------------------+-----------------+------------------------------------+ | |||
1704 | // | target | parallel | * | | |||
1705 | // | target | for | * | | |||
1706 | // | target | for simd | * | | |||
1707 | // | target | master | * | | |||
1708 | // | target | critical | * | | |||
1709 | // | target | simd | * | | |||
1710 | // | target | sections | * | | |||
1711 | // | target | section | * | | |||
1712 | // | target | single | * | | |||
1713 | // | target | parallel for | * | | |||
1714 | // | target |parallel for simd| * | | |||
1715 | // | target |parallel sections| * | | |||
1716 | // | target | task | * | | |||
1717 | // | target | taskyield | * | | |||
1718 | // | target | barrier | * | | |||
1719 | // | target | taskwait | * | | |||
1720 | // | target | taskgroup | * | | |||
1721 | // | target | flush | * | | |||
1722 | // | target | ordered | * | | |||
1723 | // | target | atomic | * | | |||
1724 | // | target | target | * | | |||
1725 | // | target | teams | * | | |||
1726 | // +------------------+-----------------+------------------------------------+ | |||
1727 | // | teams | parallel | * | | |||
1728 | // | teams | for | + | | |||
1729 | // | teams | for simd | + | | |||
1730 | // | teams | master | + | | |||
1731 | // | teams | critical | + | | |||
1732 | // | teams | simd | + | | |||
1733 | // | teams | sections | + | | |||
1734 | // | teams | section | + | | |||
1735 | // | teams | single | + | | |||
1736 | // | teams | parallel for | * | | |||
1737 | // | teams |parallel for simd| * | | |||
1738 | // | teams |parallel sections| * | | |||
1739 | // | teams | task | + | | |||
1740 | // | teams | taskyield | + | | |||
1741 | // | teams | barrier | + | | |||
1742 | // | teams | taskwait | + | | |||
1743 | // | teams | taskgroup | + | | |||
1744 | // | teams | flush | + | | |||
1745 | // | teams | ordered | + | | |||
1746 | // | teams | atomic | + | | |||
1747 | // | teams | target | + | | |||
1748 | // | teams | teams | + | | |||
1749 | // +------------------+-----------------+------------------------------------+ | |||
1750 | if (Stack->getCurScope()) { | |||
1751 | auto ParentRegion = Stack->getParentDirective(); | |||
1752 | bool NestingProhibited = false; | |||
1753 | bool CloseNesting = true; | |||
1754 | enum { | |||
1755 | NoRecommend, | |||
1756 | ShouldBeInParallelRegion, | |||
1757 | ShouldBeInOrderedRegion, | |||
1758 | ShouldBeInTargetRegion | |||
1759 | } Recommend = NoRecommend; | |||
1760 | if (isOpenMPSimdDirective(ParentRegion)) { | |||
1761 | // OpenMP [2.16, Nesting of Regions] | |||
1762 | // OpenMP constructs may not be nested inside a simd region. | |||
1763 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); | |||
1764 | return true; | |||
1765 | } | |||
1766 | if (ParentRegion == OMPD_atomic) { | |||
1767 | // OpenMP [2.16, Nesting of Regions] | |||
1768 | // OpenMP constructs may not be nested inside an atomic region. | |||
1769 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); | |||
1770 | return true; | |||
1771 | } | |||
1772 | if (CurrentRegion == OMPD_section) { | |||
1773 | // OpenMP [2.7.2, sections Construct, Restrictions] | |||
1774 | // Orphaned section directives are prohibited. That is, the section | |||
1775 | // directives must appear within the sections construct and must not be | |||
1776 | // encountered elsewhere in the sections region. | |||
1777 | if (ParentRegion != OMPD_sections && | |||
1778 | ParentRegion != OMPD_parallel_sections) { | |||
1779 | SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) | |||
1780 | << (ParentRegion != OMPD_unknown) | |||
1781 | << getOpenMPDirectiveName(ParentRegion); | |||
1782 | return true; | |||
1783 | } | |||
1784 | return false; | |||
1785 | } | |||
1786 | // Allow some constructs to be orphaned (they could be used in functions, | |||
1787 | // called from OpenMP regions with the required preconditions). | |||
1788 | if (ParentRegion == OMPD_unknown) | |||
1789 | return false; | |||
1790 | if (CurrentRegion == OMPD_master) { | |||
1791 | // OpenMP [2.16, Nesting of Regions] | |||
1792 | // A master region may not be closely nested inside a worksharing, | |||
1793 | // atomic, or explicit task region. | |||
1794 | NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || | |||
1795 | ParentRegion == OMPD_task; | |||
1796 | } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { | |||
1797 | // OpenMP [2.16, Nesting of Regions] | |||
1798 | // A critical region may not be nested (closely or otherwise) inside a | |||
1799 | // critical region with the same name. Note that this restriction is not | |||
1800 | // sufficient to prevent deadlock. | |||
1801 | SourceLocation PreviousCriticalLoc; | |||
1802 | bool DeadLock = | |||
1803 | Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( | |||
1804 | OpenMPDirectiveKind K, | |||
1805 | const DeclarationNameInfo &DNI, | |||
1806 | SourceLocation Loc) | |||
1807 | ->bool { | |||
1808 | if (K == OMPD_critical && | |||
1809 | DNI.getName() == CurrentName.getName()) { | |||
1810 | PreviousCriticalLoc = Loc; | |||
1811 | return true; | |||
1812 | } else | |||
1813 | return false; | |||
1814 | }, | |||
1815 | false /* skip top directive */); | |||
1816 | if (DeadLock) { | |||
1817 | SemaRef.Diag(StartLoc, | |||
1818 | diag::err_omp_prohibited_region_critical_same_name) | |||
1819 | << CurrentName.getName(); | |||
1820 | if (PreviousCriticalLoc.isValid()) | |||
1821 | SemaRef.Diag(PreviousCriticalLoc, | |||
1822 | diag::note_omp_previous_critical_region); | |||
1823 | return true; | |||
1824 | } | |||
1825 | } else if (CurrentRegion == OMPD_barrier) { | |||
1826 | // OpenMP [2.16, Nesting of Regions] | |||
1827 | // A barrier region may not be closely nested inside a worksharing, | |||
1828 | // explicit task, critical, ordered, atomic, or master region. | |||
1829 | NestingProhibited = | |||
1830 | isOpenMPWorksharingDirective(ParentRegion) || | |||
1831 | ParentRegion == OMPD_task || ParentRegion == OMPD_master || | |||
1832 | ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; | |||
1833 | } else if (isOpenMPWorksharingDirective(CurrentRegion) && | |||
1834 | !isOpenMPParallelDirective(CurrentRegion)) { | |||
1835 | // OpenMP [2.16, Nesting of Regions] | |||
1836 | // A worksharing region may not be closely nested inside a worksharing, | |||
1837 | // explicit task, critical, ordered, atomic, or master region. | |||
1838 | NestingProhibited = | |||
1839 | isOpenMPWorksharingDirective(ParentRegion) || | |||
1840 | ParentRegion == OMPD_task || ParentRegion == OMPD_master || | |||
1841 | ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; | |||
1842 | Recommend = ShouldBeInParallelRegion; | |||
1843 | } else if (CurrentRegion == OMPD_ordered) { | |||
1844 | // OpenMP [2.16, Nesting of Regions] | |||
1845 | // An ordered region may not be closely nested inside a critical, | |||
1846 | // atomic, or explicit task region. | |||
1847 | // An ordered region must be closely nested inside a loop region (or | |||
1848 | // parallel loop region) with an ordered clause. | |||
1849 | NestingProhibited = ParentRegion == OMPD_critical || | |||
1850 | ParentRegion == OMPD_task || | |||
1851 | !Stack->isParentOrderedRegion(); | |||
1852 | Recommend = ShouldBeInOrderedRegion; | |||
1853 | } else if (isOpenMPTeamsDirective(CurrentRegion)) { | |||
1854 | // OpenMP [2.16, Nesting of Regions] | |||
1855 | // If specified, a teams construct must be contained within a target | |||
1856 | // construct. | |||
1857 | NestingProhibited = ParentRegion != OMPD_target; | |||
1858 | Recommend = ShouldBeInTargetRegion; | |||
1859 | Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); | |||
1860 | } | |||
1861 | if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { | |||
1862 | // OpenMP [2.16, Nesting of Regions] | |||
1863 | // distribute, parallel, parallel sections, parallel workshare, and the | |||
1864 | // parallel loop and parallel loop SIMD constructs are the only OpenMP | |||
1865 | // constructs that can be closely nested in the teams region. | |||
1866 | // TODO: add distribute directive. | |||
1867 | NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); | |||
1868 | Recommend = ShouldBeInParallelRegion; | |||
1869 | } | |||
1870 | if (NestingProhibited) { | |||
1871 | SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) | |||
1872 | << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend | |||
1873 | << getOpenMPDirectiveName(CurrentRegion); | |||
1874 | return true; | |||
1875 | } | |||
1876 | } | |||
1877 | return false; | |||
1878 | } | |||
1879 | ||||
1880 | StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, | |||
1881 | const DeclarationNameInfo &DirName, | |||
1882 | ArrayRef<OMPClause *> Clauses, | |||
1883 | Stmt *AStmt, | |||
1884 | SourceLocation StartLoc, | |||
1885 | SourceLocation EndLoc) { | |||
1886 | StmtResult Res = StmtError(); | |||
1887 | if (CheckNestingOfRegions(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), Kind, DirName, StartLoc)) | |||
1888 | return StmtError(); | |||
1889 | ||||
1890 | llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; | |||
1891 | llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; | |||
1892 | bool ErrorFound = false; | |||
1893 | ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); | |||
1894 | if (AStmt) { | |||
1895 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1895, __PRETTY_FUNCTION__)); | |||
1896 | ||||
1897 | // Check default data sharing attributes for referenced variables. | |||
1898 | DSAAttrChecker DSAChecker(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), *this, cast<CapturedStmt>(AStmt)); | |||
1899 | DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); | |||
1900 | if (DSAChecker.isErrorFound()) | |||
1901 | return StmtError(); | |||
1902 | // Generate list of implicitly defined firstprivate variables. | |||
1903 | VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); | |||
1904 | ||||
1905 | if (!DSAChecker.getImplicitFirstprivate().empty()) { | |||
1906 | if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( | |||
1907 | DSAChecker.getImplicitFirstprivate(), SourceLocation(), | |||
1908 | SourceLocation(), SourceLocation())) { | |||
1909 | ClausesWithImplicit.push_back(Implicit); | |||
1910 | ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != | |||
1911 | DSAChecker.getImplicitFirstprivate().size(); | |||
1912 | } else | |||
1913 | ErrorFound = true; | |||
1914 | } | |||
1915 | } | |||
1916 | ||||
1917 | switch (Kind) { | |||
1918 | case OMPD_parallel: | |||
1919 | Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
1920 | EndLoc); | |||
1921 | break; | |||
1922 | case OMPD_simd: | |||
1923 | Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | |||
1924 | VarsWithInheritedDSA); | |||
1925 | break; | |||
1926 | case OMPD_for: | |||
1927 | Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, | |||
1928 | VarsWithInheritedDSA); | |||
1929 | break; | |||
1930 | case OMPD_for_simd: | |||
1931 | Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
1932 | EndLoc, VarsWithInheritedDSA); | |||
1933 | break; | |||
1934 | case OMPD_sections: | |||
1935 | Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
1936 | EndLoc); | |||
1937 | break; | |||
1938 | case OMPD_section: | |||
1939 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1940, __PRETTY_FUNCTION__)) | |||
1940 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1940, __PRETTY_FUNCTION__)); | |||
1941 | Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); | |||
1942 | break; | |||
1943 | case OMPD_single: | |||
1944 | Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
1945 | EndLoc); | |||
1946 | break; | |||
1947 | case OMPD_master: | |||
1948 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1949, __PRETTY_FUNCTION__)) | |||
1949 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1949, __PRETTY_FUNCTION__)); | |||
1950 | Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); | |||
1951 | break; | |||
1952 | case OMPD_critical: | |||
1953 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp critical' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp critical' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1954, __PRETTY_FUNCTION__)) | |||
1954 | "No clauses are allowed for 'omp critical' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp critical' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp critical' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1954, __PRETTY_FUNCTION__)); | |||
1955 | Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc); | |||
1956 | break; | |||
1957 | case OMPD_parallel_for: | |||
1958 | Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
1959 | EndLoc, VarsWithInheritedDSA); | |||
1960 | break; | |||
1961 | case OMPD_parallel_for_simd: | |||
1962 | Res = ActOnOpenMPParallelForSimdDirective( | |||
1963 | ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); | |||
1964 | break; | |||
1965 | case OMPD_parallel_sections: | |||
1966 | Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, | |||
1967 | StartLoc, EndLoc); | |||
1968 | break; | |||
1969 | case OMPD_task: | |||
1970 | Res = | |||
1971 | ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | |||
1972 | break; | |||
1973 | case OMPD_taskyield: | |||
1974 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1975, __PRETTY_FUNCTION__)) | |||
1975 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1975, __PRETTY_FUNCTION__)); | |||
1976 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1977, __PRETTY_FUNCTION__)) | |||
1977 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1977, __PRETTY_FUNCTION__)); | |||
1978 | Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); | |||
1979 | break; | |||
1980 | case OMPD_barrier: | |||
1981 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1982, __PRETTY_FUNCTION__)) | |||
1982 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1982, __PRETTY_FUNCTION__)); | |||
1983 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1984, __PRETTY_FUNCTION__)) | |||
1984 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1984, __PRETTY_FUNCTION__)); | |||
1985 | Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); | |||
1986 | break; | |||
1987 | case OMPD_taskwait: | |||
1988 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1989, __PRETTY_FUNCTION__)) | |||
1989 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1989, __PRETTY_FUNCTION__)); | |||
1990 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1991, __PRETTY_FUNCTION__)) | |||
1991 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1991, __PRETTY_FUNCTION__)); | |||
1992 | Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); | |||
1993 | break; | |||
1994 | case OMPD_taskgroup: | |||
1995 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskgroup' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskgroup' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1996, __PRETTY_FUNCTION__)) | |||
1996 | "No clauses are allowed for 'omp taskgroup' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp taskgroup' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp taskgroup' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 1996, __PRETTY_FUNCTION__)); | |||
1997 | Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); | |||
1998 | break; | |||
1999 | case OMPD_flush: | |||
2000 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2001, __PRETTY_FUNCTION__)) | |||
2001 | "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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2001, __PRETTY_FUNCTION__)); | |||
2002 | Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); | |||
2003 | break; | |||
2004 | case OMPD_ordered: | |||
2005 | assert(ClausesWithImplicit.empty() &&((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp ordered' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp ordered' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2006, __PRETTY_FUNCTION__)) | |||
2006 | "No clauses are allowed for 'omp ordered' directive")((ClausesWithImplicit.empty() && "No clauses are allowed for 'omp ordered' directive" ) ? static_cast<void> (0) : __assert_fail ("ClausesWithImplicit.empty() && \"No clauses are allowed for 'omp ordered' directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2006, __PRETTY_FUNCTION__)); | |||
2007 | Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); | |||
2008 | break; | |||
2009 | case OMPD_atomic: | |||
2010 | Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
2011 | EndLoc); | |||
2012 | break; | |||
2013 | case OMPD_teams: | |||
2014 | Res = | |||
2015 | ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); | |||
2016 | break; | |||
2017 | case OMPD_target: | |||
2018 | Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, | |||
2019 | EndLoc); | |||
2020 | break; | |||
2021 | case OMPD_threadprivate: | |||
2022 | llvm_unreachable("OpenMP Directive is not allowed")::llvm::llvm_unreachable_internal("OpenMP Directive is not allowed" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2022); | |||
2023 | case OMPD_unknown: | |||
2024 | llvm_unreachable("Unknown OpenMP directive")::llvm::llvm_unreachable_internal("Unknown OpenMP directive", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2024); | |||
2025 | } | |||
2026 | ||||
2027 | for (auto P : VarsWithInheritedDSA) { | |||
2028 | Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) | |||
2029 | << P.first << P.second->getSourceRange(); | |||
2030 | } | |||
2031 | if (!VarsWithInheritedDSA.empty()) | |||
2032 | return StmtError(); | |||
2033 | ||||
2034 | if (ErrorFound) | |||
2035 | return StmtError(); | |||
2036 | return Res; | |||
2037 | } | |||
2038 | ||||
2039 | StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, | |||
2040 | Stmt *AStmt, | |||
2041 | SourceLocation StartLoc, | |||
2042 | SourceLocation EndLoc) { | |||
2043 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2043, __PRETTY_FUNCTION__)); | |||
2044 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | |||
2045 | // 1.2.2 OpenMP Language Terminology | |||
2046 | // Structured block - An executable statement with a single entry at the | |||
2047 | // top and a single exit at the bottom. | |||
2048 | // The point of exit cannot be a branch out of the structured block. | |||
2049 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
2050 | CS->getCapturedDecl()->setNothrow(); | |||
2051 | ||||
2052 | getCurFunction()->setHasBranchProtectedScope(); | |||
2053 | ||||
2054 | return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, | |||
2055 | AStmt); | |||
2056 | } | |||
2057 | ||||
2058 | namespace { | |||
2059 | /// \brief Helper class for checking canonical form of the OpenMP loops and | |||
2060 | /// extracting iteration space of each loop in the loop nest, that will be used | |||
2061 | /// for IR generation. | |||
2062 | class OpenMPIterationSpaceChecker { | |||
2063 | /// \brief Reference to Sema. | |||
2064 | Sema &SemaRef; | |||
2065 | /// \brief A location for diagnostics (when there is no some better location). | |||
2066 | SourceLocation DefaultLoc; | |||
2067 | /// \brief A location for diagnostics (when increment is not compatible). | |||
2068 | SourceLocation ConditionLoc; | |||
2069 | /// \brief A source location for referring to loop init later. | |||
2070 | SourceRange InitSrcRange; | |||
2071 | /// \brief A source location for referring to condition later. | |||
2072 | SourceRange ConditionSrcRange; | |||
2073 | /// \brief A source location for referring to increment later. | |||
2074 | SourceRange IncrementSrcRange; | |||
2075 | /// \brief Loop variable. | |||
2076 | VarDecl *Var; | |||
2077 | /// \brief Reference to loop variable. | |||
2078 | DeclRefExpr *VarRef; | |||
2079 | /// \brief Lower bound (initializer for the var). | |||
2080 | Expr *LB; | |||
2081 | /// \brief Upper bound. | |||
2082 | Expr *UB; | |||
2083 | /// \brief Loop step (increment). | |||
2084 | Expr *Step; | |||
2085 | /// \brief This flag is true when condition is one of: | |||
2086 | /// Var < UB | |||
2087 | /// Var <= UB | |||
2088 | /// UB > Var | |||
2089 | /// UB >= Var | |||
2090 | bool TestIsLessOp; | |||
2091 | /// \brief This flag is true when condition is strict ( < or > ). | |||
2092 | bool TestIsStrictOp; | |||
2093 | /// \brief This flag is true when step is subtracted on each iteration. | |||
2094 | bool SubtractStep; | |||
2095 | ||||
2096 | public: | |||
2097 | OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) | |||
2098 | : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), | |||
2099 | InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), | |||
2100 | IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), | |||
2101 | LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), | |||
2102 | TestIsStrictOp(false), SubtractStep(false) {} | |||
2103 | /// \brief Check init-expr for canonical loop form and save loop counter | |||
2104 | /// variable - #Var and its initialization value - #LB. | |||
2105 | bool CheckInit(Stmt *S, bool EmitDiags = true); | |||
2106 | /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags | |||
2107 | /// for less/greater and for strict/non-strict comparison. | |||
2108 | bool CheckCond(Expr *S); | |||
2109 | /// \brief Check incr-expr for canonical loop form and return true if it | |||
2110 | /// does not conform, otherwise save loop step (#Step). | |||
2111 | bool CheckInc(Expr *S); | |||
2112 | /// \brief Return the loop counter variable. | |||
2113 | VarDecl *GetLoopVar() const { return Var; } | |||
2114 | /// \brief Return the reference expression to loop counter variable. | |||
2115 | DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } | |||
2116 | /// \brief Source range of the loop init. | |||
2117 | SourceRange GetInitSrcRange() const { return InitSrcRange; } | |||
2118 | /// \brief Source range of the loop condition. | |||
2119 | SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } | |||
2120 | /// \brief Source range of the loop increment. | |||
2121 | SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } | |||
2122 | /// \brief True if the step should be subtracted. | |||
2123 | bool ShouldSubtractStep() const { return SubtractStep; } | |||
2124 | /// \brief Build the expression to calculate the number of iterations. | |||
2125 | Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; | |||
2126 | /// \brief Build the precondition expression for the loops. | |||
2127 | Expr *BuildPreCond(Scope *S, Expr *Cond) const; | |||
2128 | /// \brief Build reference expression to the counter be used for codegen. | |||
2129 | Expr *BuildCounterVar() const; | |||
2130 | /// \brief Build initization of the counter be used for codegen. | |||
2131 | Expr *BuildCounterInit() const; | |||
2132 | /// \brief Build step of the counter be used for codegen. | |||
2133 | Expr *BuildCounterStep() const; | |||
2134 | /// \brief Return true if any expression is dependent. | |||
2135 | bool Dependent() const; | |||
2136 | ||||
2137 | private: | |||
2138 | /// \brief Check the right-hand side of an assignment in the increment | |||
2139 | /// expression. | |||
2140 | bool CheckIncRHS(Expr *RHS); | |||
2141 | /// \brief Helper to set loop counter variable and its initializer. | |||
2142 | bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB); | |||
2143 | /// \brief Helper to set upper bound. | |||
2144 | bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR, | |||
2145 | const SourceLocation &SL); | |||
2146 | /// \brief Helper to set loop increment. | |||
2147 | bool SetStep(Expr *NewStep, bool Subtract); | |||
2148 | }; | |||
2149 | ||||
2150 | bool OpenMPIterationSpaceChecker::Dependent() const { | |||
2151 | if (!Var) { | |||
2152 | assert(!LB && !UB && !Step)((!LB && !UB && !Step) ? static_cast<void> (0) : __assert_fail ("!LB && !UB && !Step", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2152, __PRETTY_FUNCTION__)); | |||
2153 | return false; | |||
2154 | } | |||
2155 | return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) || | |||
2156 | (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); | |||
2157 | } | |||
2158 | ||||
2159 | bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, | |||
2160 | DeclRefExpr *NewVarRefExpr, | |||
2161 | Expr *NewLB) { | |||
2162 | // State consistency checking to ensure correct usage. | |||
2163 | assert(Var == nullptr && LB == nullptr && VarRef == nullptr &&((Var == nullptr && LB == nullptr && VarRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void > (0) : __assert_fail ("Var == nullptr && LB == nullptr && VarRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2164, __PRETTY_FUNCTION__)) | |||
2164 | UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp)((Var == nullptr && LB == nullptr && VarRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void > (0) : __assert_fail ("Var == nullptr && LB == nullptr && VarRef == nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2164, __PRETTY_FUNCTION__)); | |||
2165 | if (!NewVar || !NewLB) | |||
2166 | return true; | |||
2167 | Var = NewVar; | |||
2168 | VarRef = NewVarRefExpr; | |||
2169 | LB = NewLB; | |||
2170 | return false; | |||
2171 | } | |||
2172 | ||||
2173 | bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, | |||
2174 | const SourceRange &SR, | |||
2175 | const SourceLocation &SL) { | |||
2176 | // State consistency checking to ensure correct usage. | |||
2177 | assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&((Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2178, __PRETTY_FUNCTION__)) | |||
2178 | !TestIsLessOp && !TestIsStrictOp)((Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp) ? static_cast<void> (0) : __assert_fail ("Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2178, __PRETTY_FUNCTION__)); | |||
2179 | if (!NewUB) | |||
2180 | return true; | |||
2181 | UB = NewUB; | |||
2182 | TestIsLessOp = LessOp; | |||
2183 | TestIsStrictOp = StrictOp; | |||
2184 | ConditionSrcRange = SR; | |||
2185 | ConditionLoc = SL; | |||
2186 | return false; | |||
2187 | } | |||
2188 | ||||
2189 | bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { | |||
2190 | // State consistency checking to ensure correct usage. | |||
2191 | assert(Var != nullptr && LB != nullptr && Step == nullptr)((Var != nullptr && LB != nullptr && Step == nullptr ) ? static_cast<void> (0) : __assert_fail ("Var != nullptr && LB != nullptr && Step == nullptr" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2191, __PRETTY_FUNCTION__)); | |||
2192 | if (!NewStep) | |||
2193 | return true; | |||
2194 | if (!NewStep->isValueDependent()) { | |||
2195 | // Check that the step is integer expression. | |||
2196 | SourceLocation StepLoc = NewStep->getLocStart(); | |||
2197 | ExprResult Val = | |||
2198 | SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); | |||
2199 | if (Val.isInvalid()) | |||
2200 | return true; | |||
2201 | NewStep = Val.get(); | |||
2202 | ||||
2203 | // OpenMP [2.6, Canonical Loop Form, Restrictions] | |||
2204 | // If test-expr is of form var relational-op b and relational-op is < or | |||
2205 | // <= then incr-expr must cause var to increase on each iteration of the | |||
2206 | // loop. If test-expr is of form var relational-op b and relational-op is | |||
2207 | // > or >= then incr-expr must cause var to decrease on each iteration of | |||
2208 | // the loop. | |||
2209 | // If test-expr is of form b relational-op var and relational-op is < or | |||
2210 | // <= then incr-expr must cause var to decrease on each iteration of the | |||
2211 | // loop. If test-expr is of form b relational-op var and relational-op is | |||
2212 | // > or >= then incr-expr must cause var to increase on each iteration of | |||
2213 | // the loop. | |||
2214 | llvm::APSInt Result; | |||
2215 | bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); | |||
2216 | bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); | |||
2217 | bool IsConstNeg = | |||
2218 | IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); | |||
2219 | bool IsConstPos = | |||
2220 | IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); | |||
2221 | bool IsConstZero = IsConstant && !Result.getBoolValue(); | |||
2222 | if (UB && (IsConstZero || | |||
2223 | (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) | |||
2224 | : (IsConstPos || (IsUnsigned && !Subtract))))) { | |||
2225 | SemaRef.Diag(NewStep->getExprLoc(), | |||
2226 | diag::err_omp_loop_incr_not_compatible) | |||
2227 | << Var << TestIsLessOp << NewStep->getSourceRange(); | |||
2228 | SemaRef.Diag(ConditionLoc, | |||
2229 | diag::note_omp_loop_cond_requres_compatible_incr) | |||
2230 | << TestIsLessOp << ConditionSrcRange; | |||
2231 | return true; | |||
2232 | } | |||
2233 | if (TestIsLessOp == Subtract) { | |||
2234 | NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, | |||
2235 | NewStep).get(); | |||
2236 | Subtract = !Subtract; | |||
2237 | } | |||
2238 | } | |||
2239 | ||||
2240 | Step = NewStep; | |||
2241 | SubtractStep = Subtract; | |||
2242 | return false; | |||
2243 | } | |||
2244 | ||||
2245 | bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { | |||
2246 | // Check init-expr for canonical loop form and save loop counter | |||
2247 | // variable - #Var and its initialization value - #LB. | |||
2248 | // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: | |||
2249 | // var = lb | |||
2250 | // integer-type var = lb | |||
2251 | // random-access-iterator-type var = lb | |||
2252 | // pointer-type var = lb | |||
2253 | // | |||
2254 | if (!S) { | |||
2255 | if (EmitDiags) { | |||
2256 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); | |||
2257 | } | |||
2258 | return true; | |||
2259 | } | |||
2260 | InitSrcRange = S->getSourceRange(); | |||
2261 | if (Expr *E = dyn_cast<Expr>(S)) | |||
2262 | S = E->IgnoreParens(); | |||
2263 | if (auto BO = dyn_cast<BinaryOperator>(S)) { | |||
2264 | if (BO->getOpcode() == BO_Assign) | |||
2265 | if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) | |||
2266 | return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, | |||
2267 | BO->getRHS()); | |||
2268 | } else if (auto DS = dyn_cast<DeclStmt>(S)) { | |||
2269 | if (DS->isSingleDecl()) { | |||
2270 | if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { | |||
2271 | if (Var->hasInit()) { | |||
2272 | // Accept non-canonical init form here but emit ext. warning. | |||
2273 | if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) | |||
2274 | SemaRef.Diag(S->getLocStart(), | |||
2275 | diag::ext_omp_loop_not_canonical_init) | |||
2276 | << S->getSourceRange(); | |||
2277 | return SetVarAndLB(Var, nullptr, Var->getInit()); | |||
2278 | } | |||
2279 | } | |||
2280 | } | |||
2281 | } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) | |||
2282 | if (CE->getOperator() == OO_Equal) | |||
2283 | if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) | |||
2284 | return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, | |||
2285 | CE->getArg(1)); | |||
2286 | ||||
2287 | if (EmitDiags) { | |||
2288 | SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) | |||
2289 | << S->getSourceRange(); | |||
2290 | } | |||
2291 | return true; | |||
2292 | } | |||
2293 | ||||
2294 | /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the | |||
2295 | /// variable (which may be the loop variable) if possible. | |||
2296 | static const VarDecl *GetInitVarDecl(const Expr *E) { | |||
2297 | if (!E) | |||
2298 | return nullptr; | |||
2299 | E = E->IgnoreParenImpCasts(); | |||
2300 | if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) | |||
2301 | if (const CXXConstructorDecl *Ctor = CE->getConstructor()) | |||
2302 | if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && | |||
2303 | CE->getArg(0) != nullptr) | |||
2304 | E = CE->getArg(0)->IgnoreParenImpCasts(); | |||
2305 | auto DRE = dyn_cast_or_null<DeclRefExpr>(E); | |||
2306 | if (!DRE) | |||
2307 | return nullptr; | |||
2308 | return dyn_cast<VarDecl>(DRE->getDecl()); | |||
2309 | } | |||
2310 | ||||
2311 | bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { | |||
2312 | // Check test-expr for canonical form, save upper-bound UB, flags for | |||
2313 | // less/greater and for strict/non-strict comparison. | |||
2314 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | |||
2315 | // var relational-op b | |||
2316 | // b relational-op var | |||
2317 | // | |||
2318 | if (!S) { | |||
2319 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; | |||
2320 | return true; | |||
2321 | } | |||
2322 | S = S->IgnoreParenImpCasts(); | |||
2323 | SourceLocation CondLoc = S->getLocStart(); | |||
2324 | if (auto BO = dyn_cast<BinaryOperator>(S)) { | |||
2325 | if (BO->isRelationalOp()) { | |||
2326 | if (GetInitVarDecl(BO->getLHS()) == Var) | |||
2327 | return SetUB(BO->getRHS(), | |||
2328 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), | |||
2329 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | |||
2330 | BO->getSourceRange(), BO->getOperatorLoc()); | |||
2331 | if (GetInitVarDecl(BO->getRHS()) == Var) | |||
2332 | return SetUB(BO->getLHS(), | |||
2333 | (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), | |||
2334 | (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), | |||
2335 | BO->getSourceRange(), BO->getOperatorLoc()); | |||
2336 | } | |||
2337 | } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { | |||
2338 | if (CE->getNumArgs() == 2) { | |||
2339 | auto Op = CE->getOperator(); | |||
2340 | switch (Op) { | |||
2341 | case OO_Greater: | |||
2342 | case OO_GreaterEqual: | |||
2343 | case OO_Less: | |||
2344 | case OO_LessEqual: | |||
2345 | if (GetInitVarDecl(CE->getArg(0)) == Var) | |||
2346 | return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, | |||
2347 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | |||
2348 | CE->getOperatorLoc()); | |||
2349 | if (GetInitVarDecl(CE->getArg(1)) == Var) | |||
2350 | return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, | |||
2351 | Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), | |||
2352 | CE->getOperatorLoc()); | |||
2353 | break; | |||
2354 | default: | |||
2355 | break; | |||
2356 | } | |||
2357 | } | |||
2358 | } | |||
2359 | SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) | |||
2360 | << S->getSourceRange() << Var; | |||
2361 | return true; | |||
2362 | } | |||
2363 | ||||
2364 | bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { | |||
2365 | // RHS of canonical loop form increment can be: | |||
2366 | // var + incr | |||
2367 | // incr + var | |||
2368 | // var - incr | |||
2369 | // | |||
2370 | RHS = RHS->IgnoreParenImpCasts(); | |||
2371 | if (auto BO = dyn_cast<BinaryOperator>(RHS)) { | |||
2372 | if (BO->isAdditiveOp()) { | |||
2373 | bool IsAdd = BO->getOpcode() == BO_Add; | |||
2374 | if (GetInitVarDecl(BO->getLHS()) == Var) | |||
2375 | return SetStep(BO->getRHS(), !IsAdd); | |||
2376 | if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var) | |||
2377 | return SetStep(BO->getLHS(), false); | |||
2378 | } | |||
2379 | } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { | |||
2380 | bool IsAdd = CE->getOperator() == OO_Plus; | |||
2381 | if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { | |||
2382 | if (GetInitVarDecl(CE->getArg(0)) == Var) | |||
2383 | return SetStep(CE->getArg(1), !IsAdd); | |||
2384 | if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var) | |||
2385 | return SetStep(CE->getArg(0), false); | |||
2386 | } | |||
2387 | } | |||
2388 | SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) | |||
2389 | << RHS->getSourceRange() << Var; | |||
2390 | return true; | |||
2391 | } | |||
2392 | ||||
2393 | bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { | |||
2394 | // Check incr-expr for canonical loop form and return true if it | |||
2395 | // does not conform. | |||
2396 | // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: | |||
2397 | // ++var | |||
2398 | // var++ | |||
2399 | // --var | |||
2400 | // var-- | |||
2401 | // var += incr | |||
2402 | // var -= incr | |||
2403 | // var = var + incr | |||
2404 | // var = incr + var | |||
2405 | // var = var - incr | |||
2406 | // | |||
2407 | if (!S) { | |||
2408 | SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var; | |||
2409 | return true; | |||
2410 | } | |||
2411 | IncrementSrcRange = S->getSourceRange(); | |||
2412 | S = S->IgnoreParens(); | |||
2413 | if (auto UO = dyn_cast<UnaryOperator>(S)) { | |||
2414 | if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) | |||
2415 | return SetStep( | |||
2416 | SemaRef.ActOnIntegerConstant(UO->getLocStart(), | |||
2417 | (UO->isDecrementOp() ? -1 : 1)).get(), | |||
2418 | false); | |||
2419 | } else if (auto BO = dyn_cast<BinaryOperator>(S)) { | |||
2420 | switch (BO->getOpcode()) { | |||
2421 | case BO_AddAssign: | |||
2422 | case BO_SubAssign: | |||
2423 | if (GetInitVarDecl(BO->getLHS()) == Var) | |||
2424 | return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); | |||
2425 | break; | |||
2426 | case BO_Assign: | |||
2427 | if (GetInitVarDecl(BO->getLHS()) == Var) | |||
2428 | return CheckIncRHS(BO->getRHS()); | |||
2429 | break; | |||
2430 | default: | |||
2431 | break; | |||
2432 | } | |||
2433 | } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { | |||
2434 | switch (CE->getOperator()) { | |||
2435 | case OO_PlusPlus: | |||
2436 | case OO_MinusMinus: | |||
2437 | if (GetInitVarDecl(CE->getArg(0)) == Var) | |||
2438 | return SetStep( | |||
2439 | SemaRef.ActOnIntegerConstant( | |||
2440 | CE->getLocStart(), | |||
2441 | ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), | |||
2442 | false); | |||
2443 | break; | |||
2444 | case OO_PlusEqual: | |||
2445 | case OO_MinusEqual: | |||
2446 | if (GetInitVarDecl(CE->getArg(0)) == Var) | |||
2447 | return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); | |||
2448 | break; | |||
2449 | case OO_Equal: | |||
2450 | if (GetInitVarDecl(CE->getArg(0)) == Var) | |||
2451 | return CheckIncRHS(CE->getArg(1)); | |||
2452 | break; | |||
2453 | default: | |||
2454 | break; | |||
2455 | } | |||
2456 | } | |||
2457 | SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) | |||
2458 | << S->getSourceRange() << Var; | |||
2459 | return true; | |||
2460 | } | |||
2461 | ||||
2462 | /// \brief Build the expression to calculate the number of iterations. | |||
2463 | Expr * | |||
2464 | OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, | |||
2465 | const bool LimitedType) const { | |||
2466 | ExprResult Diff; | |||
2467 | if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || | |||
2468 | SemaRef.getLangOpts().CPlusPlus) { | |||
2469 | // Upper - Lower | |||
2470 | Expr *Upper = TestIsLessOp ? UB : LB; | |||
2471 | Expr *Lower = TestIsLessOp ? LB : UB; | |||
2472 | ||||
2473 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); | |||
2474 | ||||
2475 | if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { | |||
2476 | // BuildBinOp already emitted error, this one is to point user to upper | |||
2477 | // and lower bound, and to tell what is passed to 'operator-'. | |||
2478 | SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) | |||
2479 | << Upper->getSourceRange() << Lower->getSourceRange(); | |||
2480 | return nullptr; | |||
2481 | } | |||
2482 | } | |||
2483 | ||||
2484 | if (!Diff.isUsable()) | |||
2485 | return nullptr; | |||
2486 | ||||
2487 | // Upper - Lower [- 1] | |||
2488 | if (TestIsStrictOp) | |||
2489 | Diff = SemaRef.BuildBinOp( | |||
2490 | S, DefaultLoc, BO_Sub, Diff.get(), | |||
2491 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | |||
2492 | if (!Diff.isUsable()) | |||
2493 | return nullptr; | |||
2494 | ||||
2495 | // Upper - Lower [- 1] + Step | |||
2496 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), | |||
2497 | Step->IgnoreImplicit()); | |||
2498 | if (!Diff.isUsable()) | |||
2499 | return nullptr; | |||
2500 | ||||
2501 | // Parentheses (for dumping/debugging purposes only). | |||
2502 | Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); | |||
2503 | if (!Diff.isUsable()) | |||
2504 | return nullptr; | |||
2505 | ||||
2506 | // (Upper - Lower [- 1] + Step) / Step | |||
2507 | Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), | |||
2508 | Step->IgnoreImplicit()); | |||
2509 | if (!Diff.isUsable()) | |||
2510 | return nullptr; | |||
2511 | ||||
2512 | // OpenMP runtime requires 32-bit or 64-bit loop variables. | |||
2513 | if (LimitedType) { | |||
2514 | auto &C = SemaRef.Context; | |||
2515 | QualType Type = Diff.get()->getType(); | |||
2516 | unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; | |||
2517 | if (NewSize != C.getTypeSize(Type)) { | |||
2518 | if (NewSize < C.getTypeSize(Type)) { | |||
2519 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2519, __PRETTY_FUNCTION__)); | |||
2520 | SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) | |||
2521 | << InitSrcRange << ConditionSrcRange; | |||
2522 | } | |||
2523 | QualType NewType = C.getIntTypeForBitwidth( | |||
2524 | NewSize, Type->hasSignedIntegerRepresentation()); | |||
2525 | Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, | |||
2526 | Sema::AA_Converting, true); | |||
2527 | if (!Diff.isUsable()) | |||
2528 | return nullptr; | |||
2529 | } | |||
2530 | } | |||
2531 | ||||
2532 | return Diff.get(); | |||
2533 | } | |||
2534 | ||||
2535 | Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { | |||
2536 | // Try to build LB <op> UB, where <op> is <, >, <=, or >=. | |||
2537 | bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); | |||
2538 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); | |||
2539 | auto CondExpr = SemaRef.BuildBinOp( | |||
2540 | S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) | |||
2541 | : (TestIsStrictOp ? BO_GT : BO_GE), | |||
2542 | LB, UB); | |||
2543 | SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); | |||
2544 | // Otherwise use original loop conditon and evaluate it in runtime. | |||
2545 | return CondExpr.isUsable() ? CondExpr.get() : Cond; | |||
2546 | } | |||
2547 | ||||
2548 | /// \brief Build reference expression to the counter be used for codegen. | |||
2549 | Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { | |||
2550 | return buildDeclRefExpr(SemaRef, Var, Var->getType(), DefaultLoc); | |||
2551 | } | |||
2552 | ||||
2553 | /// \brief Build initization of the counter be used for codegen. | |||
2554 | Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } | |||
2555 | ||||
2556 | /// \brief Build step of the counter be used for codegen. | |||
2557 | Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } | |||
2558 | ||||
2559 | /// \brief Iteration space of a single for loop. | |||
2560 | struct LoopIterationSpace { | |||
2561 | /// \brief Condition of the loop. | |||
2562 | Expr *PreCond; | |||
2563 | /// \brief This expression calculates the number of iterations in the loop. | |||
2564 | /// It is always possible to calculate it before starting the loop. | |||
2565 | Expr *NumIterations; | |||
2566 | /// \brief The loop counter variable. | |||
2567 | Expr *CounterVar; | |||
2568 | /// \brief This is initializer for the initial value of #CounterVar. | |||
2569 | Expr *CounterInit; | |||
2570 | /// \brief This is step for the #CounterVar used to generate its update: | |||
2571 | /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. | |||
2572 | Expr *CounterStep; | |||
2573 | /// \brief Should step be subtracted? | |||
2574 | bool Subtract; | |||
2575 | /// \brief Source range of the loop init. | |||
2576 | SourceRange InitSrcRange; | |||
2577 | /// \brief Source range of the loop condition. | |||
2578 | SourceRange CondSrcRange; | |||
2579 | /// \brief Source range of the loop increment. | |||
2580 | SourceRange IncSrcRange; | |||
2581 | }; | |||
2582 | ||||
2583 | } // namespace | |||
2584 | ||||
2585 | void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { | |||
2586 | 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.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2586, __PRETTY_FUNCTION__)); | |||
2587 | 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.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2587, __PRETTY_FUNCTION__)); | |||
2588 | unsigned CollapseIteration = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCollapseNumber(); | |||
2589 | if (CollapseIteration > 0 && | |||
2590 | isOpenMPLoopDirective(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | |||
2591 | OpenMPIterationSpaceChecker ISC(*this, ForLoc); | |||
2592 | if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { | |||
2593 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addLoopControlVariable(ISC.GetLoopVar()); | |||
2594 | } | |||
2595 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setCollapseNumber(CollapseIteration - 1); | |||
2596 | } | |||
2597 | } | |||
2598 | ||||
2599 | /// \brief Called on a for stmt to check and extract its iteration space | |||
2600 | /// for further processing (such as collapsing). | |||
2601 | static bool CheckOpenMPIterationSpace( | |||
2602 | OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, | |||
2603 | unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, | |||
2604 | Expr *NestedLoopCountExpr, | |||
2605 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, | |||
2606 | LoopIterationSpace &ResultIterSpace) { | |||
2607 | // OpenMP [2.6, Canonical Loop Form] | |||
2608 | // for (init-expr; test-expr; incr-expr) structured-block | |||
2609 | auto For = dyn_cast_or_null<ForStmt>(S); | |||
2610 | if (!For) { | |||
| ||||
2611 | SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) | |||
2612 | << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind) | |||
2613 | << NestedLoopCount << (CurrentNestedLoopCount > 0) | |||
2614 | << CurrentNestedLoopCount; | |||
2615 | if (NestedLoopCount > 1) | |||
2616 | SemaRef.Diag(NestedLoopCountExpr->getExprLoc(), | |||
| ||||
2617 | diag::note_omp_collapse_expr) | |||
2618 | << NestedLoopCountExpr->getSourceRange(); | |||
2619 | return true; | |||
2620 | } | |||
2621 | assert(For->getBody())((For->getBody()) ? static_cast<void> (0) : __assert_fail ("For->getBody()", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2621, __PRETTY_FUNCTION__)); | |||
2622 | ||||
2623 | OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); | |||
2624 | ||||
2625 | // Check init. | |||
2626 | auto Init = For->getInit(); | |||
2627 | if (ISC.CheckInit(Init)) { | |||
2628 | return true; | |||
2629 | } | |||
2630 | ||||
2631 | bool HasErrors = false; | |||
2632 | ||||
2633 | // Check loop variable's type. | |||
2634 | auto Var = ISC.GetLoopVar(); | |||
2635 | ||||
2636 | // OpenMP [2.6, Canonical Loop Form] | |||
2637 | // Var is one of the following: | |||
2638 | // A variable of signed or unsigned integer type. | |||
2639 | // For C++, a variable of a random access iterator type. | |||
2640 | // For C, a variable of a pointer type. | |||
2641 | auto VarType = Var->getType(); | |||
2642 | if (!VarType->isDependentType() && !VarType->isIntegerType() && | |||
2643 | !VarType->isPointerType() && | |||
2644 | !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { | |||
2645 | SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) | |||
2646 | << SemaRef.getLangOpts().CPlusPlus; | |||
2647 | HasErrors = true; | |||
2648 | } | |||
2649 | ||||
2650 | // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a | |||
2651 | // Construct | |||
2652 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | |||
2653 | // parallel for construct is (are) private. | |||
2654 | // The loop iteration variable in the associated for-loop of a simd construct | |||
2655 | // with just one associated for-loop is linear with a constant-linear-step | |||
2656 | // that is the increment of the associated for-loop. | |||
2657 | // Exclude loop var from the list of variables with implicitly defined data | |||
2658 | // sharing attributes. | |||
2659 | VarsWithImplicitDSA.erase(Var); | |||
2660 | ||||
2661 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in | |||
2662 | // a Construct, C/C++]. | |||
2663 | // The loop iteration variable in the associated for-loop of a simd construct | |||
2664 | // with just one associated for-loop may be listed in a linear clause with a | |||
2665 | // constant-linear-step that is the increment of the associated for-loop. | |||
2666 | // The loop iteration variable(s) in the associated for-loop(s) of a for or | |||
2667 | // parallel for construct may be listed in a private or lastprivate clause. | |||
2668 | DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); | |||
2669 | auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); | |||
2670 | // If LoopVarRefExpr is nullptr it means the corresponding loop variable is | |||
2671 | // declared in the loop and it is predetermined as a private. | |||
2672 | auto PredeterminedCKind = | |||
2673 | isOpenMPSimdDirective(DKind) | |||
2674 | ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) | |||
2675 | : OMPC_private; | |||
2676 | if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && | |||
2677 | DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) || | |||
2678 | (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && | |||
2679 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && | |||
2680 | DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_threadprivate)) && | |||
2681 | ((DVar.CKind != OMPC_private && DVar.CKind != OMPC_threadprivate) || | |||
2682 | DVar.RefExpr != nullptr)) { | |||
2683 | SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) | |||
2684 | << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) | |||
2685 | << getOpenMPClauseName(PredeterminedCKind); | |||
2686 | if (DVar.RefExpr == nullptr) | |||
2687 | DVar.CKind = PredeterminedCKind; | |||
2688 | ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true); | |||
2689 | HasErrors = true; | |||
2690 | } else if (LoopVarRefExpr != nullptr) { | |||
2691 | // Make the loop iteration variable private (for worksharing constructs), | |||
2692 | // linear (for simd directives with the only one associated loop) or | |||
2693 | // lastprivate (for simd directives with several collapsed loops). | |||
2694 | if (DVar.CKind == OMPC_unknown) | |||
2695 | DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), | |||
2696 | /*FromParent=*/false); | |||
2697 | DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind); | |||
2698 | } | |||
2699 | ||||
2700 | 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\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 2700, __PRETTY_FUNCTION__)); | |||
2701 | ||||
2702 | // Check test-expr. | |||
2703 | HasErrors |= ISC.CheckCond(For->getCond()); | |||
2704 | ||||
2705 | // Check incr-expr. | |||
2706 | HasErrors |= ISC.CheckInc(For->getInc()); | |||
2707 | ||||
2708 | if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) | |||
2709 | return HasErrors; | |||
2710 | ||||
2711 | // Build the loop's iteration space representation. | |||
2712 | ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); | |||
2713 | ResultIterSpace.NumIterations = ISC.BuildNumIterations( | |||
2714 | DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); | |||
2715 | ResultIterSpace.CounterVar = ISC.BuildCounterVar(); | |||
2716 | ResultIterSpace.CounterInit = ISC.BuildCounterInit(); | |||
2717 | ResultIterSpace.CounterStep = ISC.BuildCounterStep(); | |||
2718 | ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); | |||
2719 | ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); | |||
2720 | ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); | |||
2721 | ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); | |||
2722 | ||||
2723 | HasErrors |= (ResultIterSpace.PreCond == nullptr || | |||
2724 | ResultIterSpace.NumIterations == nullptr || | |||
2725 | ResultIterSpace.CounterVar == nullptr || | |||
2726 | ResultIterSpace.CounterInit == nullptr || | |||
2727 | ResultIterSpace.CounterStep == nullptr); | |||
2728 | ||||
2729 | return HasErrors; | |||
2730 | } | |||
2731 | ||||
2732 | /// \brief Build 'VarRef = Start + Iter * Step'. | |||
2733 | static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, | |||
2734 | SourceLocation Loc, ExprResult VarRef, | |||
2735 | ExprResult Start, ExprResult Iter, | |||
2736 | ExprResult Step, bool Subtract) { | |||
2737 | // Add parentheses (for debugging purposes only). | |||
2738 | Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); | |||
2739 | if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || | |||
2740 | !Step.isUsable()) | |||
2741 | return ExprError(); | |||
2742 | ||||
2743 | ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), | |||
2744 | Step.get()->IgnoreImplicit()); | |||
2745 | if (!Update.isUsable()) | |||
2746 | return ExprError(); | |||
2747 | ||||
2748 | // Build 'VarRef = Start + Iter * Step'. | |||
2749 | Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), | |||
2750 | Start.get()->IgnoreImplicit(), Update.get()); | |||
2751 | if (!Update.isUsable()) | |||
2752 | return ExprError(); | |||
2753 | ||||
2754 | Update = SemaRef.PerformImplicitConversion( | |||
2755 | Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); | |||
2756 | if (!Update.isUsable()) | |||
2757 | return ExprError(); | |||
2758 | ||||
2759 | Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); | |||
2760 | return Update; | |||
2761 | } | |||
2762 | ||||
2763 | /// \brief Convert integer expression \a E to make it have at least \a Bits | |||
2764 | /// bits. | |||
2765 | static ExprResult WidenIterationCount(unsigned Bits, Expr *E, | |||
2766 | Sema &SemaRef) { | |||
2767 | if (E == nullptr) | |||
2768 | return ExprError(); | |||
2769 | auto &C = SemaRef.Context; | |||
2770 | QualType OldType = E->getType(); | |||
2771 | unsigned HasBits = C.getTypeSize(OldType); | |||
2772 | if (HasBits >= Bits) | |||
2773 | return ExprResult(E); | |||
2774 | // OK to convert to signed, because new type has more bits than old. | |||
2775 | QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); | |||
2776 | return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, | |||
2777 | true); | |||
2778 | } | |||
2779 | ||||
2780 | /// \brief Check if the given expression \a E is a constant integer that fits | |||
2781 | /// into \a Bits bits. | |||
2782 | static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { | |||
2783 | if (E == nullptr) | |||
2784 | return false; | |||
2785 | llvm::APSInt Result; | |||
2786 | if (E->isIntegerConstantExpr(Result, SemaRef.Context)) | |||
2787 | return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); | |||
2788 | return false; | |||
2789 | } | |||
2790 | ||||
2791 | /// \brief Called on a for stmt to check itself and nested loops (if any). | |||
2792 | /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, | |||
2793 | /// number of collapsed loops otherwise. | |||
2794 | static unsigned | |||
2795 | CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, | |||
2796 | Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, | |||
2797 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, | |||
2798 | OMPLoopDirective::HelperExprs &Built) { | |||
2799 | unsigned NestedLoopCount = 1; | |||
2800 | if (NestedLoopCountExpr) { | |||
2801 | // Found 'collapse' clause - calculate collapse number. | |||
2802 | llvm::APSInt Result; | |||
2803 | if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) | |||
2804 | NestedLoopCount = Result.getLimitedValue(); | |||
2805 | } | |||
2806 | // This is helper routine for loop directives (e.g., 'for', 'simd', | |||
2807 | // 'for simd', etc.). | |||
2808 | SmallVector<LoopIterationSpace, 4> IterSpaces; | |||
2809 | IterSpaces.resize(NestedLoopCount); | |||
2810 | Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); | |||
2811 | for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { | |||
2812 | if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, | |||
2813 | NestedLoopCount, NestedLoopCountExpr, | |||
2814 | VarsWithImplicitDSA, IterSpaces[Cnt])) | |||
2815 | return 0; | |||
2816 | // Move on to the next nested for loop, or to the loop body. | |||
2817 | // OpenMP [2.8.1, simd construct, Restrictions] | |||
2818 | // All loops associated with the construct must be perfectly nested; that | |||
2819 | // is, there must be no intervening code nor any OpenMP directive between | |||
2820 | // any two loops. | |||
2821 | CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); | |||
2822 | } | |||
2823 | ||||
2824 | Built.clear(/* size */ NestedLoopCount); | |||
2825 | ||||
2826 | if (SemaRef.CurContext->isDependentContext()) | |||
2827 | return NestedLoopCount; | |||
2828 | ||||
2829 | // An example of what is generated for the following code: | |||
2830 | // | |||
2831 | // #pragma omp simd collapse(2) | |||
2832 | // for (i = 0; i < NI; ++i) | |||
2833 | // for (j = J0; j < NJ; j+=2) { | |||
2834 | // <loop body> | |||
2835 | // } | |||
2836 | // | |||
2837 | // We generate the code below. | |||
2838 | // Note: the loop body may be outlined in CodeGen. | |||
2839 | // Note: some counters may be C++ classes, operator- is used to find number of | |||
2840 | // iterations and operator+= to calculate counter value. | |||
2841 | // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 | |||
2842 | // or i64 is currently supported). | |||
2843 | // | |||
2844 | // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) | |||
2845 | // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { | |||
2846 | // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); | |||
2847 | // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; | |||
2848 | // // similar updates for vars in clauses (e.g. 'linear') | |||
2849 | // <loop body (using local i and j)> | |||
2850 | // } | |||
2851 | // i = NI; // assign final values of counters | |||
2852 | // j = NJ; | |||
2853 | // | |||
2854 | ||||
2855 | // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are | |||
2856 | // the iteration counts of the collapsed for loops. | |||
2857 | // Precondition tests if there is at least one iteration (all conditions are | |||
2858 | // true). | |||
2859 | auto PreCond = ExprResult(IterSpaces[0].PreCond); | |||
2860 | auto N0 = IterSpaces[0].NumIterations; | |||
2861 | ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); | |||
2862 | ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); | |||
2863 | ||||
2864 | if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) | |||
2865 | return NestedLoopCount; | |||
2866 | ||||
2867 | auto &C = SemaRef.Context; | |||
2868 | bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; | |||
2869 | ||||
2870 | Scope *CurScope = DSA.getCurScope(); | |||
2871 | for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { | |||
2872 | if (PreCond.isUsable()) { | |||
2873 | PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, | |||
2874 | PreCond.get(), IterSpaces[Cnt].PreCond); | |||
2875 | } | |||
2876 | auto N = IterSpaces[Cnt].NumIterations; | |||
2877 | AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; | |||
2878 | if (LastIteration32.isUsable()) | |||
2879 | LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, | |||
2880 | LastIteration32.get(), N); | |||
2881 | if (LastIteration64.isUsable()) | |||
2882 | LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, | |||
2883 | LastIteration64.get(), N); | |||
2884 | } | |||
2885 | ||||
2886 | // Choose either the 32-bit or 64-bit version. | |||
2887 | ExprResult LastIteration = LastIteration64; | |||
2888 | if (LastIteration32.isUsable() && | |||
2889 | C.getTypeSize(LastIteration32.get()->getType()) == 32 && | |||
2890 | (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || | |||
2891 | FitsInto( | |||
2892 | 32 /* Bits */, | |||
2893 | LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), | |||
2894 | LastIteration64.get(), SemaRef))) | |||
2895 | LastIteration = LastIteration32; | |||
2896 | ||||
2897 | if (!LastIteration.isUsable()) | |||
2898 | return 0; | |||
2899 | ||||
2900 | // Save the number of iterations. | |||
2901 | ExprResult NumIterations = LastIteration; | |||
2902 | { | |||
2903 | LastIteration = SemaRef.BuildBinOp( | |||
2904 | CurScope, SourceLocation(), BO_Sub, LastIteration.get(), | |||
2905 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | |||
2906 | if (!LastIteration.isUsable()) | |||
2907 | return 0; | |||
2908 | } | |||
2909 | ||||
2910 | // Calculate the last iteration number beforehand instead of doing this on | |||
2911 | // each iteration. Do not do this if the number of iterations may be kfold-ed. | |||
2912 | llvm::APSInt Result; | |||
2913 | bool IsConstant = | |||
2914 | LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); | |||
2915 | ExprResult CalcLastIteration; | |||
2916 | if (!IsConstant) { | |||
2917 | SourceLocation SaveLoc; | |||
2918 | VarDecl *SaveVar = | |||
2919 | buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), | |||
2920 | ".omp.last.iteration"); | |||
2921 | ExprResult SaveRef = buildDeclRefExpr( | |||
2922 | SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc); | |||
2923 | CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, | |||
2924 | SaveRef.get(), LastIteration.get()); | |||
2925 | LastIteration = SaveRef; | |||
2926 | ||||
2927 | // Prepare SaveRef + 1. | |||
2928 | NumIterations = SemaRef.BuildBinOp( | |||
2929 | CurScope, SaveLoc, BO_Add, SaveRef.get(), | |||
2930 | SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); | |||
2931 | if (!NumIterations.isUsable()) | |||
2932 | return 0; | |||
2933 | } | |||
2934 | ||||
2935 | SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); | |||
2936 | ||||
2937 | QualType VType = LastIteration.get()->getType(); | |||
2938 | // Build variables passed into runtime, nesessary for worksharing directives. | |||
2939 | ExprResult LB, UB, IL, ST, EUB; | |||
2940 | if (isOpenMPWorksharingDirective(DKind)) { | |||
2941 | // Lower bound variable, initialized with zero. | |||
2942 | VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); | |||
2943 | LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); | |||
2944 | SemaRef.AddInitializerToDecl( | |||
2945 | LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | |||
2946 | /*DirectInit*/ false, /*TypeMayContainAuto*/ false); | |||
2947 | ||||
2948 | // Upper bound variable, initialized with last iteration number. | |||
2949 | VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); | |||
2950 | UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); | |||
2951 | SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), | |||
2952 | /*DirectInit*/ false, | |||
2953 | /*TypeMayContainAuto*/ false); | |||
2954 | ||||
2955 | // A 32-bit variable-flag where runtime returns 1 for the last iteration. | |||
2956 | // This will be used to implement clause 'lastprivate'. | |||
2957 | QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); | |||
2958 | VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); | |||
2959 | IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); | |||
2960 | SemaRef.AddInitializerToDecl( | |||
2961 | ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), | |||
2962 | /*DirectInit*/ false, /*TypeMayContainAuto*/ false); | |||
2963 | ||||
2964 | // Stride variable returned by runtime (we initialize it to 1 by default). | |||
2965 | VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); | |||
2966 | ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); | |||
2967 | SemaRef.AddInitializerToDecl( | |||
2968 | STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), | |||
2969 | /*DirectInit*/ false, /*TypeMayContainAuto*/ false); | |||
2970 | ||||
2971 | // Build expression: UB = min(UB, LastIteration) | |||
2972 | // It is nesessary for CodeGen of directives with static scheduling. | |||
2973 | ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, | |||
2974 | UB.get(), LastIteration.get()); | |||
2975 | ExprResult CondOp = SemaRef.ActOnConditionalOp( | |||
2976 | InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); | |||
2977 | EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), | |||
2978 | CondOp.get()); | |||
2979 | EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); | |||
2980 | } | |||
2981 | ||||
2982 | // Build the iteration variable and its initialization before loop. | |||
2983 | ExprResult IV; | |||
2984 | ExprResult Init; | |||
2985 | { | |||
2986 | VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); | |||
2987 | IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); | |||
2988 | Expr *RHS = isOpenMPWorksharingDirective(DKind) | |||
2989 | ? LB.get() | |||
2990 | : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); | |||
2991 | Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); | |||
2992 | Init = SemaRef.ActOnFinishFullExpr(Init.get()); | |||
2993 | } | |||
2994 | ||||
2995 | // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. | |||
2996 | SourceLocation CondLoc; | |||
2997 | ExprResult Cond = | |||
2998 | isOpenMPWorksharingDirective(DKind) | |||
2999 | ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) | |||
3000 | : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), | |||
3001 | NumIterations.get()); | |||
3002 | ||||
3003 | // Loop increment (IV = IV + 1) | |||
3004 | SourceLocation IncLoc; | |||
3005 | ExprResult Inc = | |||
3006 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), | |||
3007 | SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); | |||
3008 | if (!Inc.isUsable()) | |||
3009 | return 0; | |||
3010 | Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); | |||
3011 | Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); | |||
3012 | if (!Inc.isUsable()) | |||
3013 | return 0; | |||
3014 | ||||
3015 | // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). | |||
3016 | // Used for directives with static scheduling. | |||
3017 | ExprResult NextLB, NextUB; | |||
3018 | if (isOpenMPWorksharingDirective(DKind)) { | |||
3019 | // LB + ST | |||
3020 | NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); | |||
3021 | if (!NextLB.isUsable()) | |||
3022 | return 0; | |||
3023 | // LB = LB + ST | |||
3024 | NextLB = | |||
3025 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); | |||
3026 | NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); | |||
3027 | if (!NextLB.isUsable()) | |||
3028 | return 0; | |||
3029 | // UB + ST | |||
3030 | NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); | |||
3031 | if (!NextUB.isUsable()) | |||
3032 | return 0; | |||
3033 | // UB = UB + ST | |||
3034 | NextUB = | |||
3035 | SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); | |||
3036 | NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); | |||
3037 | if (!NextUB.isUsable()) | |||
3038 | return 0; | |||
3039 | } | |||
3040 | ||||
3041 | // Build updates and final values of the loop counters. | |||
3042 | bool HasErrors = false; | |||
3043 | Built.Counters.resize(NestedLoopCount); | |||
3044 | Built.Updates.resize(NestedLoopCount); | |||
3045 | Built.Finals.resize(NestedLoopCount); | |||
3046 | { | |||
3047 | ExprResult Div; | |||
3048 | // Go from inner nested loop to outer. | |||
3049 | for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { | |||
3050 | LoopIterationSpace &IS = IterSpaces[Cnt]; | |||
3051 | SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); | |||
3052 | // Build: Iter = (IV / Div) % IS.NumIters | |||
3053 | // where Div is product of previous iterations' IS.NumIters. | |||
3054 | ExprResult Iter; | |||
3055 | if (Div.isUsable()) { | |||
3056 | Iter = | |||
3057 | SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); | |||
3058 | } else { | |||
3059 | Iter = IV; | |||
3060 | assert((Cnt == (int)NestedLoopCount - 1) &&(((Cnt == (int)NestedLoopCount - 1) && "unusable div expected on first iteration only" ) ? static_cast<void> (0) : __assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3061, __PRETTY_FUNCTION__)) | |||
3061 | "unusable div expected on first iteration only")(((Cnt == (int)NestedLoopCount - 1) && "unusable div expected on first iteration only" ) ? static_cast<void> (0) : __assert_fail ("(Cnt == (int)NestedLoopCount - 1) && \"unusable div expected on first iteration only\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3061, __PRETTY_FUNCTION__)); | |||
3062 | } | |||
3063 | ||||
3064 | if (Cnt != 0 && Iter.isUsable()) | |||
3065 | Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), | |||
3066 | IS.NumIterations); | |||
3067 | if (!Iter.isUsable()) { | |||
3068 | HasErrors = true; | |||
3069 | break; | |||
3070 | } | |||
3071 | ||||
3072 | // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step | |||
3073 | auto *CounterVar = buildDeclRefExpr( | |||
3074 | SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), | |||
3075 | IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), | |||
3076 | /*RefersToCapture=*/true); | |||
3077 | ExprResult Update = | |||
3078 | BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, | |||
3079 | IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); | |||
3080 | if (!Update.isUsable()) { | |||
3081 | HasErrors = true; | |||
3082 | break; | |||
3083 | } | |||
3084 | ||||
3085 | // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step | |||
3086 | ExprResult Final = BuildCounterUpdate( | |||
3087 | SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, | |||
3088 | IS.NumIterations, IS.CounterStep, IS.Subtract); | |||
3089 | if (!Final.isUsable()) { | |||
3090 | HasErrors = true; | |||
3091 | break; | |||
3092 | } | |||
3093 | ||||
3094 | // Build Div for the next iteration: Div <- Div * IS.NumIters | |||
3095 | if (Cnt != 0) { | |||
3096 | if (Div.isUnset()) | |||
3097 | Div = IS.NumIterations; | |||
3098 | else | |||
3099 | Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), | |||
3100 | IS.NumIterations); | |||
3101 | ||||
3102 | // Add parentheses (for debugging purposes only). | |||
3103 | if (Div.isUsable()) | |||
3104 | Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); | |||
3105 | if (!Div.isUsable()) { | |||
3106 | HasErrors = true; | |||
3107 | break; | |||
3108 | } | |||
3109 | } | |||
3110 | if (!Update.isUsable() || !Final.isUsable()) { | |||
3111 | HasErrors = true; | |||
3112 | break; | |||
3113 | } | |||
3114 | // Save results | |||
3115 | Built.Counters[Cnt] = IS.CounterVar; | |||
3116 | Built.Updates[Cnt] = Update.get(); | |||
3117 | Built.Finals[Cnt] = Final.get(); | |||
3118 | } | |||
3119 | } | |||
3120 | ||||
3121 | if (HasErrors) | |||
3122 | return 0; | |||
3123 | ||||
3124 | // Save results | |||
3125 | Built.IterationVarRef = IV.get(); | |||
3126 | Built.LastIteration = LastIteration.get(); | |||
3127 | Built.NumIterations = NumIterations.get(); | |||
3128 | Built.CalcLastIteration = CalcLastIteration.get(); | |||
3129 | Built.PreCond = PreCond.get(); | |||
3130 | Built.Cond = Cond.get(); | |||
3131 | Built.Init = Init.get(); | |||
3132 | Built.Inc = Inc.get(); | |||
3133 | Built.LB = LB.get(); | |||
3134 | Built.UB = UB.get(); | |||
3135 | Built.IL = IL.get(); | |||
3136 | Built.ST = ST.get(); | |||
3137 | Built.EUB = EUB.get(); | |||
3138 | Built.NLB = NextLB.get(); | |||
3139 | Built.NUB = NextUB.get(); | |||
3140 | ||||
3141 | return NestedLoopCount; | |||
3142 | } | |||
3143 | ||||
3144 | static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { | |||
3145 | auto &&CollapseFilter = [](const OMPClause *C) -> bool { | |||
3146 | return C->getClauseKind() == OMPC_collapse; | |||
3147 | }; | |||
3148 | OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( | |||
3149 | Clauses, std::move(CollapseFilter)); | |||
3150 | if (I) | |||
3151 | return cast<OMPCollapseClause>(*I)->getNumForLoops(); | |||
3152 | return nullptr; | |||
3153 | } | |||
3154 | ||||
3155 | StmtResult Sema::ActOnOpenMPSimdDirective( | |||
3156 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | |||
3157 | SourceLocation EndLoc, | |||
3158 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { | |||
3159 | OMPLoopDirective::HelperExprs B; | |||
3160 | // In presence of clause 'collapse', it will define the nested loops number. | |||
3161 | unsigned NestedLoopCount = | |||
3162 | CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this, | |||
3163 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | |||
3164 | if (NestedLoopCount == 0) | |||
3165 | return StmtError(); | |||
3166 | ||||
3167 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3168, __PRETTY_FUNCTION__)) | |||
3168 | "omp simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp simd loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp simd loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3168, __PRETTY_FUNCTION__)); | |||
3169 | ||||
3170 | if (!CurContext->isDependentContext()) { | |||
3171 | // Finalize the clauses that need pre-built expressions for CodeGen. | |||
3172 | for (auto C : Clauses) { | |||
3173 | if (auto LC = dyn_cast<OMPLinearClause>(C)) | |||
3174 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | |||
3175 | B.NumIterations, *this, CurScope)) | |||
3176 | return StmtError(); | |||
3177 | } | |||
3178 | } | |||
3179 | ||||
3180 | getCurFunction()->setHasBranchProtectedScope(); | |||
3181 | return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | |||
3182 | Clauses, AStmt, B); | |||
3183 | } | |||
3184 | ||||
3185 | StmtResult Sema::ActOnOpenMPForDirective( | |||
3186 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | |||
3187 | SourceLocation EndLoc, | |||
3188 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { | |||
3189 | OMPLoopDirective::HelperExprs B; | |||
3190 | // In presence of clause 'collapse', it will define the nested loops number. | |||
3191 | unsigned NestedLoopCount = | |||
3192 | CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this, | |||
3193 | *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | |||
3194 | if (NestedLoopCount == 0) | |||
3195 | return StmtError(); | |||
3196 | ||||
3197 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3198, __PRETTY_FUNCTION__)) | |||
3198 | "omp for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built") ? static_cast<void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3198, __PRETTY_FUNCTION__)); | |||
3199 | ||||
3200 | getCurFunction()->setHasBranchProtectedScope(); | |||
3201 | return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | |||
3202 | Clauses, AStmt, B); | |||
3203 | } | |||
3204 | ||||
3205 | StmtResult Sema::ActOnOpenMPForSimdDirective( | |||
3206 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | |||
3207 | SourceLocation EndLoc, | |||
3208 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { | |||
3209 | OMPLoopDirective::HelperExprs B; | |||
3210 | // In presence of clause 'collapse', it will define the nested loops number. | |||
3211 | unsigned NestedLoopCount = | |||
3212 | CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt, | |||
3213 | *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | |||
3214 | if (NestedLoopCount == 0) | |||
3215 | return StmtError(); | |||
3216 | ||||
3217 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3218, __PRETTY_FUNCTION__)) | |||
3218 | "omp for simd loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp for simd loop exprs were not built") ? static_cast<void > (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp for simd loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3218, __PRETTY_FUNCTION__)); | |||
3219 | ||||
3220 | if (!CurContext->isDependentContext()) { | |||
3221 | // Finalize the clauses that need pre-built expressions for CodeGen. | |||
3222 | for (auto C : Clauses) { | |||
3223 | if (auto LC = dyn_cast<OMPLinearClause>(C)) | |||
3224 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | |||
3225 | B.NumIterations, *this, CurScope)) | |||
3226 | return StmtError(); | |||
3227 | } | |||
3228 | } | |||
3229 | ||||
3230 | getCurFunction()->setHasBranchProtectedScope(); | |||
3231 | return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, | |||
3232 | Clauses, AStmt, B); | |||
3233 | } | |||
3234 | ||||
3235 | StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, | |||
3236 | Stmt *AStmt, | |||
3237 | SourceLocation StartLoc, | |||
3238 | SourceLocation EndLoc) { | |||
3239 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3239, __PRETTY_FUNCTION__)); | |||
3240 | auto BaseStmt = AStmt; | |||
3241 | while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | |||
3242 | BaseStmt = CS->getCapturedStmt(); | |||
3243 | if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | |||
3244 | auto S = C->children(); | |||
3245 | if (!S) | |||
3246 | return StmtError(); | |||
3247 | // All associated statements must be '#pragma omp section' except for | |||
3248 | // the first one. | |||
3249 | for (++S; S; ++S) { | |||
3250 | auto SectionStmt = *S; | |||
3251 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | |||
3252 | if (SectionStmt) | |||
3253 | Diag(SectionStmt->getLocStart(), | |||
3254 | diag::err_omp_sections_substmt_not_section); | |||
3255 | return StmtError(); | |||
3256 | } | |||
3257 | } | |||
3258 | } else { | |||
3259 | Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); | |||
3260 | return StmtError(); | |||
3261 | } | |||
3262 | ||||
3263 | getCurFunction()->setHasBranchProtectedScope(); | |||
3264 | ||||
3265 | return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, | |||
3266 | AStmt); | |||
3267 | } | |||
3268 | ||||
3269 | StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, | |||
3270 | SourceLocation StartLoc, | |||
3271 | SourceLocation EndLoc) { | |||
3272 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3272, __PRETTY_FUNCTION__)); | |||
3273 | ||||
3274 | getCurFunction()->setHasBranchProtectedScope(); | |||
3275 | ||||
3276 | return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt); | |||
3277 | } | |||
3278 | ||||
3279 | StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, | |||
3280 | Stmt *AStmt, | |||
3281 | SourceLocation StartLoc, | |||
3282 | SourceLocation EndLoc) { | |||
3283 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3283, __PRETTY_FUNCTION__)); | |||
3284 | ||||
3285 | getCurFunction()->setHasBranchProtectedScope(); | |||
3286 | ||||
3287 | // OpenMP [2.7.3, single Construct, Restrictions] | |||
3288 | // The copyprivate clause must not be used with the nowait clause. | |||
3289 | OMPClause *Nowait = nullptr; | |||
3290 | OMPClause *Copyprivate = nullptr; | |||
3291 | for (auto *Clause : Clauses) { | |||
3292 | if (Clause->getClauseKind() == OMPC_nowait) | |||
3293 | Nowait = Clause; | |||
3294 | else if (Clause->getClauseKind() == OMPC_copyprivate) | |||
3295 | Copyprivate = Clause; | |||
3296 | if (Copyprivate && Nowait) { | |||
3297 | Diag(Copyprivate->getLocStart(), | |||
3298 | diag::err_omp_single_copyprivate_with_nowait); | |||
3299 | Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); | |||
3300 | return StmtError(); | |||
3301 | } | |||
3302 | } | |||
3303 | ||||
3304 | return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | |||
3305 | } | |||
3306 | ||||
3307 | StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, | |||
3308 | SourceLocation StartLoc, | |||
3309 | SourceLocation EndLoc) { | |||
3310 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3310, __PRETTY_FUNCTION__)); | |||
3311 | ||||
3312 | getCurFunction()->setHasBranchProtectedScope(); | |||
3313 | ||||
3314 | return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); | |||
3315 | } | |||
3316 | ||||
3317 | StmtResult | |||
3318 | Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, | |||
3319 | Stmt *AStmt, SourceLocation StartLoc, | |||
3320 | SourceLocation EndLoc) { | |||
3321 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3321, __PRETTY_FUNCTION__)); | |||
3322 | ||||
3323 | getCurFunction()->setHasBranchProtectedScope(); | |||
3324 | ||||
3325 | return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, | |||
3326 | AStmt); | |||
3327 | } | |||
3328 | ||||
3329 | StmtResult Sema::ActOnOpenMPParallelForDirective( | |||
3330 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | |||
3331 | SourceLocation EndLoc, | |||
3332 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { | |||
3333 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3333, __PRETTY_FUNCTION__)); | |||
3334 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | |||
3335 | // 1.2.2 OpenMP Language Terminology | |||
3336 | // Structured block - An executable statement with a single entry at the | |||
3337 | // top and a single exit at the bottom. | |||
3338 | // The point of exit cannot be a branch out of the structured block. | |||
3339 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
3340 | CS->getCapturedDecl()->setNothrow(); | |||
3341 | ||||
3342 | OMPLoopDirective::HelperExprs B; | |||
3343 | // In presence of clause 'collapse', it will define the nested loops number. | |||
3344 | unsigned NestedLoopCount = | |||
3345 | CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt, | |||
3346 | *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | |||
3347 | if (NestedLoopCount == 0) | |||
3348 | return StmtError(); | |||
3349 | ||||
3350 | assert((CurContext->isDependentContext() || B.builtAll()) &&(((CurContext->isDependentContext() || B.builtAll()) && "omp parallel for loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3351, __PRETTY_FUNCTION__)) | |||
3351 | "omp parallel for loop exprs were not built")(((CurContext->isDependentContext() || B.builtAll()) && "omp parallel for loop exprs were not built") ? static_cast< void> (0) : __assert_fail ("(CurContext->isDependentContext() || B.builtAll()) && \"omp parallel for loop exprs were not built\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3351, __PRETTY_FUNCTION__)); | |||
3352 | ||||
3353 | getCurFunction()->setHasBranchProtectedScope(); | |||
3354 | return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, | |||
3355 | NestedLoopCount, Clauses, AStmt, B); | |||
3356 | } | |||
3357 | ||||
3358 | StmtResult Sema::ActOnOpenMPParallelForSimdDirective( | |||
3359 | ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, | |||
3360 | SourceLocation EndLoc, | |||
3361 | llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { | |||
3362 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3362, __PRETTY_FUNCTION__)); | |||
3363 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | |||
3364 | // 1.2.2 OpenMP Language Terminology | |||
3365 | // Structured block - An executable statement with a single entry at the | |||
3366 | // top and a single exit at the bottom. | |||
3367 | // The point of exit cannot be a branch out of the structured block. | |||
3368 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
3369 | CS->getCapturedDecl()->setNothrow(); | |||
3370 | ||||
3371 | OMPLoopDirective::HelperExprs B; | |||
3372 | // In presence of clause 'collapse', it will define the nested loops number. | |||
3373 | unsigned NestedLoopCount = | |||
3374 | CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses), | |||
3375 | AStmt, *this, *DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VarsWithImplicitDSA, B); | |||
3376 | if (NestedLoopCount == 0) | |||
3377 | return StmtError(); | |||
3378 | ||||
3379 | if (!CurContext->isDependentContext()) { | |||
3380 | // Finalize the clauses that need pre-built expressions for CodeGen. | |||
3381 | for (auto C : Clauses) { | |||
3382 | if (auto LC = dyn_cast<OMPLinearClause>(C)) | |||
3383 | if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), | |||
3384 | B.NumIterations, *this, CurScope)) | |||
3385 | return StmtError(); | |||
3386 | } | |||
3387 | } | |||
3388 | ||||
3389 | getCurFunction()->setHasBranchProtectedScope(); | |||
3390 | return OMPParallelForSimdDirective::Create( | |||
3391 | Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); | |||
3392 | } | |||
3393 | ||||
3394 | StmtResult | |||
3395 | Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, | |||
3396 | Stmt *AStmt, SourceLocation StartLoc, | |||
3397 | SourceLocation EndLoc) { | |||
3398 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3398, __PRETTY_FUNCTION__)); | |||
3399 | auto BaseStmt = AStmt; | |||
3400 | while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) | |||
3401 | BaseStmt = CS->getCapturedStmt(); | |||
3402 | if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { | |||
3403 | auto S = C->children(); | |||
3404 | if (!S) | |||
3405 | return StmtError(); | |||
3406 | // All associated statements must be '#pragma omp section' except for | |||
3407 | // the first one. | |||
3408 | for (++S; S; ++S) { | |||
3409 | auto SectionStmt = *S; | |||
3410 | if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { | |||
3411 | if (SectionStmt) | |||
3412 | Diag(SectionStmt->getLocStart(), | |||
3413 | diag::err_omp_parallel_sections_substmt_not_section); | |||
3414 | return StmtError(); | |||
3415 | } | |||
3416 | } | |||
3417 | } else { | |||
3418 | Diag(AStmt->getLocStart(), | |||
3419 | diag::err_omp_parallel_sections_not_compound_stmt); | |||
3420 | return StmtError(); | |||
3421 | } | |||
3422 | ||||
3423 | getCurFunction()->setHasBranchProtectedScope(); | |||
3424 | ||||
3425 | return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, | |||
3426 | Clauses, AStmt); | |||
3427 | } | |||
3428 | ||||
3429 | StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, | |||
3430 | Stmt *AStmt, SourceLocation StartLoc, | |||
3431 | SourceLocation EndLoc) { | |||
3432 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3432, __PRETTY_FUNCTION__)); | |||
3433 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | |||
3434 | // 1.2.2 OpenMP Language Terminology | |||
3435 | // Structured block - An executable statement with a single entry at the | |||
3436 | // top and a single exit at the bottom. | |||
3437 | // The point of exit cannot be a branch out of the structured block. | |||
3438 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
3439 | CS->getCapturedDecl()->setNothrow(); | |||
3440 | ||||
3441 | getCurFunction()->setHasBranchProtectedScope(); | |||
3442 | ||||
3443 | return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | |||
3444 | } | |||
3445 | ||||
3446 | StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, | |||
3447 | SourceLocation EndLoc) { | |||
3448 | return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); | |||
3449 | } | |||
3450 | ||||
3451 | StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, | |||
3452 | SourceLocation EndLoc) { | |||
3453 | return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); | |||
3454 | } | |||
3455 | ||||
3456 | StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, | |||
3457 | SourceLocation EndLoc) { | |||
3458 | return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); | |||
3459 | } | |||
3460 | ||||
3461 | StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, | |||
3462 | SourceLocation StartLoc, | |||
3463 | SourceLocation EndLoc) { | |||
3464 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3464, __PRETTY_FUNCTION__)); | |||
3465 | ||||
3466 | getCurFunction()->setHasBranchProtectedScope(); | |||
3467 | ||||
3468 | return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); | |||
3469 | } | |||
3470 | ||||
3471 | StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, | |||
3472 | SourceLocation StartLoc, | |||
3473 | SourceLocation EndLoc) { | |||
3474 | assert(Clauses.size() <= 1 && "Extra clauses in flush directive")((Clauses.size() <= 1 && "Extra clauses in flush directive" ) ? static_cast<void> (0) : __assert_fail ("Clauses.size() <= 1 && \"Extra clauses in flush directive\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3474, __PRETTY_FUNCTION__)); | |||
3475 | return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); | |||
3476 | } | |||
3477 | ||||
3478 | StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, | |||
3479 | SourceLocation StartLoc, | |||
3480 | SourceLocation EndLoc) { | |||
3481 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3481, __PRETTY_FUNCTION__)); | |||
3482 | ||||
3483 | getCurFunction()->setHasBranchProtectedScope(); | |||
3484 | ||||
3485 | return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); | |||
3486 | } | |||
3487 | ||||
3488 | namespace { | |||
3489 | /// \brief Helper class for checking expression in 'omp atomic [update]' | |||
3490 | /// construct. | |||
3491 | class OpenMPAtomicUpdateChecker { | |||
3492 | /// \brief Error results for atomic update expressions. | |||
3493 | enum ExprAnalysisErrorCode { | |||
3494 | /// \brief A statement is not an expression statement. | |||
3495 | NotAnExpression, | |||
3496 | /// \brief Expression is not builtin binary or unary operation. | |||
3497 | NotABinaryOrUnaryExpression, | |||
3498 | /// \brief Unary operation is not post-/pre- increment/decrement operation. | |||
3499 | NotAnUnaryIncDecExpression, | |||
3500 | /// \brief An expression is not of scalar type. | |||
3501 | NotAScalarType, | |||
3502 | /// \brief A binary operation is not an assignment operation. | |||
3503 | NotAnAssignmentOp, | |||
3504 | /// \brief RHS part of the binary operation is not a binary expression. | |||
3505 | NotABinaryExpression, | |||
3506 | /// \brief RHS part is not additive/multiplicative/shift/biwise binary | |||
3507 | /// expression. | |||
3508 | NotABinaryOperator, | |||
3509 | /// \brief RHS binary operation does not have reference to the updated LHS | |||
3510 | /// part. | |||
3511 | NotAnUpdateExpression, | |||
3512 | /// \brief No errors is found. | |||
3513 | NoError | |||
3514 | }; | |||
3515 | /// \brief Reference to Sema. | |||
3516 | Sema &SemaRef; | |||
3517 | /// \brief A location for note diagnostics (when error is found). | |||
3518 | SourceLocation NoteLoc; | |||
3519 | /// \brief 'x' lvalue part of the source atomic expression. | |||
3520 | Expr *X; | |||
3521 | /// \brief 'expr' rvalue part of the source atomic expression. | |||
3522 | Expr *E; | |||
3523 | /// \brief Helper expression of the form | |||
3524 | /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | |||
3525 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | |||
3526 | Expr *UpdateExpr; | |||
3527 | /// \brief Is 'x' a LHS in a RHS part of full update expression. It is | |||
3528 | /// important for non-associative operations. | |||
3529 | bool IsXLHSInRHSPart; | |||
3530 | BinaryOperatorKind Op; | |||
3531 | SourceLocation OpLoc; | |||
3532 | /// \brief true if the source expression is a postfix unary operation, false | |||
3533 | /// if it is a prefix unary operation. | |||
3534 | bool IsPostfixUpdate; | |||
3535 | ||||
3536 | public: | |||
3537 | OpenMPAtomicUpdateChecker(Sema &SemaRef) | |||
3538 | : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), | |||
3539 | IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} | |||
3540 | /// \brief Check specified statement that it is suitable for 'atomic update' | |||
3541 | /// constructs and extract 'x', 'expr' and Operation from the original | |||
3542 | /// expression. If DiagId and NoteId == 0, then only check is performed | |||
3543 | /// without error notification. | |||
3544 | /// \param DiagId Diagnostic which should be emitted if error is found. | |||
3545 | /// \param NoteId Diagnostic note for the main error message. | |||
3546 | /// \return true if statement is not an update expression, false otherwise. | |||
3547 | bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); | |||
3548 | /// \brief Return the 'x' lvalue part of the source atomic expression. | |||
3549 | Expr *getX() const { return X; } | |||
3550 | /// \brief Return the 'expr' rvalue part of the source atomic expression. | |||
3551 | Expr *getExpr() const { return E; } | |||
3552 | /// \brief Return the update expression used in calculation of the updated | |||
3553 | /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or | |||
3554 | /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. | |||
3555 | Expr *getUpdateExpr() const { return UpdateExpr; } | |||
3556 | /// \brief Return true if 'x' is LHS in RHS part of full update expression, | |||
3557 | /// false otherwise. | |||
3558 | bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } | |||
3559 | ||||
3560 | /// \brief true if the source expression is a postfix unary operation, false | |||
3561 | /// if it is a prefix unary operation. | |||
3562 | bool isPostfixUpdate() const { return IsPostfixUpdate; } | |||
3563 | ||||
3564 | private: | |||
3565 | bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, | |||
3566 | unsigned NoteId = 0); | |||
3567 | }; | |||
3568 | } // namespace | |||
3569 | ||||
3570 | bool OpenMPAtomicUpdateChecker::checkBinaryOperation( | |||
3571 | BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { | |||
3572 | ExprAnalysisErrorCode ErrorFound = NoError; | |||
3573 | SourceLocation ErrorLoc, NoteLoc; | |||
3574 | SourceRange ErrorRange, NoteRange; | |||
3575 | // Allowed constructs are: | |||
3576 | // x = x binop expr; | |||
3577 | // x = expr binop x; | |||
3578 | if (AtomicBinOp->getOpcode() == BO_Assign) { | |||
3579 | X = AtomicBinOp->getLHS(); | |||
3580 | if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( | |||
3581 | AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { | |||
3582 | if (AtomicInnerBinOp->isMultiplicativeOp() || | |||
3583 | AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || | |||
3584 | AtomicInnerBinOp->isBitwiseOp()) { | |||
3585 | Op = AtomicInnerBinOp->getOpcode(); | |||
3586 | OpLoc = AtomicInnerBinOp->getOperatorLoc(); | |||
3587 | auto *LHS = AtomicInnerBinOp->getLHS(); | |||
3588 | auto *RHS = AtomicInnerBinOp->getRHS(); | |||
3589 | llvm::FoldingSetNodeID XId, LHSId, RHSId; | |||
3590 | X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), | |||
3591 | /*Canonical=*/true); | |||
3592 | LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), | |||
3593 | /*Canonical=*/true); | |||
3594 | RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), | |||
3595 | /*Canonical=*/true); | |||
3596 | if (XId == LHSId) { | |||
3597 | E = RHS; | |||
3598 | IsXLHSInRHSPart = true; | |||
3599 | } else if (XId == RHSId) { | |||
3600 | E = LHS; | |||
3601 | IsXLHSInRHSPart = false; | |||
3602 | } else { | |||
3603 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | |||
3604 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | |||
3605 | NoteLoc = X->getExprLoc(); | |||
3606 | NoteRange = X->getSourceRange(); | |||
3607 | ErrorFound = NotAnUpdateExpression; | |||
3608 | } | |||
3609 | } else { | |||
3610 | ErrorLoc = AtomicInnerBinOp->getExprLoc(); | |||
3611 | ErrorRange = AtomicInnerBinOp->getSourceRange(); | |||
3612 | NoteLoc = AtomicInnerBinOp->getOperatorLoc(); | |||
3613 | NoteRange = SourceRange(NoteLoc, NoteLoc); | |||
3614 | ErrorFound = NotABinaryOperator; | |||
3615 | } | |||
3616 | } else { | |||
3617 | NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); | |||
3618 | NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); | |||
3619 | ErrorFound = NotABinaryExpression; | |||
3620 | } | |||
3621 | } else { | |||
3622 | ErrorLoc = AtomicBinOp->getExprLoc(); | |||
3623 | ErrorRange = AtomicBinOp->getSourceRange(); | |||
3624 | NoteLoc = AtomicBinOp->getOperatorLoc(); | |||
3625 | NoteRange = SourceRange(NoteLoc, NoteLoc); | |||
3626 | ErrorFound = NotAnAssignmentOp; | |||
3627 | } | |||
3628 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | |||
3629 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | |||
3630 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | |||
3631 | return true; | |||
3632 | } else if (SemaRef.CurContext->isDependentContext()) | |||
3633 | E = X = UpdateExpr = nullptr; | |||
3634 | return ErrorFound != NoError; | |||
3635 | } | |||
3636 | ||||
3637 | bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, | |||
3638 | unsigned NoteId) { | |||
3639 | ExprAnalysisErrorCode ErrorFound = NoError; | |||
3640 | SourceLocation ErrorLoc, NoteLoc; | |||
3641 | SourceRange ErrorRange, NoteRange; | |||
3642 | // Allowed constructs are: | |||
3643 | // x++; | |||
3644 | // x--; | |||
3645 | // ++x; | |||
3646 | // --x; | |||
3647 | // x binop= expr; | |||
3648 | // x = x binop expr; | |||
3649 | // x = expr binop x; | |||
3650 | if (auto *AtomicBody = dyn_cast<Expr>(S)) { | |||
3651 | AtomicBody = AtomicBody->IgnoreParenImpCasts(); | |||
3652 | if (AtomicBody->getType()->isScalarType() || | |||
3653 | AtomicBody->isInstantiationDependent()) { | |||
3654 | if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( | |||
3655 | AtomicBody->IgnoreParenImpCasts())) { | |||
3656 | // Check for Compound Assignment Operation | |||
3657 | Op = BinaryOperator::getOpForCompoundAssignment( | |||
3658 | AtomicCompAssignOp->getOpcode()); | |||
3659 | OpLoc = AtomicCompAssignOp->getOperatorLoc(); | |||
3660 | E = AtomicCompAssignOp->getRHS(); | |||
3661 | X = AtomicCompAssignOp->getLHS(); | |||
3662 | IsXLHSInRHSPart = true; | |||
3663 | } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( | |||
3664 | AtomicBody->IgnoreParenImpCasts())) { | |||
3665 | // Check for Binary Operation | |||
3666 | if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) | |||
3667 | return true; | |||
3668 | } else if (auto *AtomicUnaryOp = | |||
3669 | dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { | |||
3670 | // Check for Unary Operation | |||
3671 | if (AtomicUnaryOp->isIncrementDecrementOp()) { | |||
3672 | IsPostfixUpdate = AtomicUnaryOp->isPostfix(); | |||
3673 | Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; | |||
3674 | OpLoc = AtomicUnaryOp->getOperatorLoc(); | |||
3675 | X = AtomicUnaryOp->getSubExpr(); | |||
3676 | E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); | |||
3677 | IsXLHSInRHSPart = true; | |||
3678 | } else { | |||
3679 | ErrorFound = NotAnUnaryIncDecExpression; | |||
3680 | ErrorLoc = AtomicUnaryOp->getExprLoc(); | |||
3681 | ErrorRange = AtomicUnaryOp->getSourceRange(); | |||
3682 | NoteLoc = AtomicUnaryOp->getOperatorLoc(); | |||
3683 | NoteRange = SourceRange(NoteLoc, NoteLoc); | |||
3684 | } | |||
3685 | } else { | |||
3686 | ErrorFound = NotABinaryOrUnaryExpression; | |||
3687 | NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); | |||
3688 | NoteRange = ErrorRange = AtomicBody->getSourceRange(); | |||
3689 | } | |||
3690 | } else { | |||
3691 | ErrorFound = NotAScalarType; | |||
3692 | NoteLoc = ErrorLoc = AtomicBody->getLocStart(); | |||
3693 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | |||
3694 | } | |||
3695 | } else { | |||
3696 | ErrorFound = NotAnExpression; | |||
3697 | NoteLoc = ErrorLoc = S->getLocStart(); | |||
3698 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | |||
3699 | } | |||
3700 | if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { | |||
3701 | SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; | |||
3702 | SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; | |||
3703 | return true; | |||
3704 | } else if (SemaRef.CurContext->isDependentContext()) | |||
3705 | E = X = UpdateExpr = nullptr; | |||
3706 | if (ErrorFound == NoError && E && X) { | |||
3707 | // Build an update expression of form 'OpaqueValueExpr(x) binop | |||
3708 | // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop | |||
3709 | // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. | |||
3710 | auto *OVEX = new (SemaRef.getASTContext()) | |||
3711 | OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); | |||
3712 | auto *OVEExpr = new (SemaRef.getASTContext()) | |||
3713 | OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); | |||
3714 | auto Update = | |||
3715 | SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, | |||
3716 | IsXLHSInRHSPart ? OVEExpr : OVEX); | |||
3717 | if (Update.isInvalid()) | |||
3718 | return true; | |||
3719 | Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), | |||
3720 | Sema::AA_Casting); | |||
3721 | if (Update.isInvalid()) | |||
3722 | return true; | |||
3723 | UpdateExpr = Update.get(); | |||
3724 | } | |||
3725 | return ErrorFound != NoError; | |||
3726 | } | |||
3727 | ||||
3728 | StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, | |||
3729 | Stmt *AStmt, | |||
3730 | SourceLocation StartLoc, | |||
3731 | SourceLocation EndLoc) { | |||
3732 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 3732, __PRETTY_FUNCTION__)); | |||
3733 | auto CS = cast<CapturedStmt>(AStmt); | |||
3734 | // 1.2.2 OpenMP Language Terminology | |||
3735 | // Structured block - An executable statement with a single entry at the | |||
3736 | // top and a single exit at the bottom. | |||
3737 | // The point of exit cannot be a branch out of the structured block. | |||
3738 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
3739 | OpenMPClauseKind AtomicKind = OMPC_unknown; | |||
3740 | SourceLocation AtomicKindLoc; | |||
3741 | for (auto *C : Clauses) { | |||
3742 | if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || | |||
3743 | C->getClauseKind() == OMPC_update || | |||
3744 | C->getClauseKind() == OMPC_capture) { | |||
3745 | if (AtomicKind != OMPC_unknown) { | |||
3746 | Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) | |||
3747 | << SourceRange(C->getLocStart(), C->getLocEnd()); | |||
3748 | Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) | |||
3749 | << getOpenMPClauseName(AtomicKind); | |||
3750 | } else { | |||
3751 | AtomicKind = C->getClauseKind(); | |||
3752 | AtomicKindLoc = C->getLocStart(); | |||
3753 | } | |||
3754 | } | |||
3755 | } | |||
3756 | ||||
3757 | auto Body = CS->getCapturedStmt(); | |||
3758 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) | |||
3759 | Body = EWC->getSubExpr(); | |||
3760 | ||||
3761 | Expr *X = nullptr; | |||
3762 | Expr *V = nullptr; | |||
3763 | Expr *E = nullptr; | |||
3764 | Expr *UE = nullptr; | |||
3765 | bool IsXLHSInRHSPart = false; | |||
3766 | bool IsPostfixUpdate = false; | |||
3767 | // OpenMP [2.12.6, atomic Construct] | |||
3768 | // In the next expressions: | |||
3769 | // * x and v (as applicable) are both l-value expressions with scalar type. | |||
3770 | // * During the execution of an atomic region, multiple syntactic | |||
3771 | // occurrences of x must designate the same storage location. | |||
3772 | // * Neither of v and expr (as applicable) may access the storage location | |||
3773 | // designated by x. | |||
3774 | // * Neither of x and expr (as applicable) may access the storage location | |||
3775 | // designated by v. | |||
3776 | // * expr is an expression with scalar type. | |||
3777 | // * binop is one of +, *, -, /, &, ^, |, <<, or >>. | |||
3778 | // * binop, binop=, ++, and -- are not overloaded operators. | |||
3779 | // * The expression x binop expr must be numerically equivalent to x binop | |||
3780 | // (expr). This requirement is satisfied if the operators in expr have | |||
3781 | // precedence greater than binop, or by using parentheses around expr or | |||
3782 | // subexpressions of expr. | |||
3783 | // * The expression expr binop x must be numerically equivalent to (expr) | |||
3784 | // binop x. This requirement is satisfied if the operators in expr have | |||
3785 | // precedence equal to or greater than binop, or by using parentheses around | |||
3786 | // expr or subexpressions of expr. | |||
3787 | // * For forms that allow multiple occurrences of x, the number of times | |||
3788 | // that x is evaluated is unspecified. | |||
3789 | if (AtomicKind == OMPC_read) { | |||
3790 | enum { | |||
3791 | NotAnExpression, | |||
3792 | NotAnAssignmentOp, | |||
3793 | NotAScalarType, | |||
3794 | NotAnLValue, | |||
3795 | NoError | |||
3796 | } ErrorFound = NoError; | |||
3797 | SourceLocation ErrorLoc, NoteLoc; | |||
3798 | SourceRange ErrorRange, NoteRange; | |||
3799 | // If clause is read: | |||
3800 | // v = x; | |||
3801 | if (auto AtomicBody = dyn_cast<Expr>(Body)) { | |||
3802 | auto AtomicBinOp = | |||
3803 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | |||
3804 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | |||
3805 | X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | |||
3806 | V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); | |||
3807 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | |||
3808 | (V->isInstantiationDependent() || V->getType()->isScalarType())) { | |||
3809 | if (!X->isLValue() || !V->isLValue()) { | |||
3810 | auto NotLValueExpr = X->isLValue() ? V : X; | |||
3811 | ErrorFound = NotAnLValue; | |||
3812 | ErrorLoc = AtomicBinOp->getExprLoc(); | |||
3813 | ErrorRange = AtomicBinOp->getSourceRange(); | |||
3814 | NoteLoc = NotLValueExpr->getExprLoc(); | |||
3815 | NoteRange = NotLValueExpr->getSourceRange(); | |||
3816 | } | |||
3817 | } else if (!X->isInstantiationDependent() || | |||
3818 | !V->isInstantiationDependent()) { | |||
3819 | auto NotScalarExpr = | |||
3820 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | |||
3821 | ? V | |||
3822 | : X; | |||
3823 | ErrorFound = NotAScalarType; | |||
3824 | ErrorLoc = AtomicBinOp->getExprLoc(); | |||
3825 | ErrorRange = AtomicBinOp->getSourceRange(); | |||
3826 | NoteLoc = NotScalarExpr->getExprLoc(); | |||
3827 | NoteRange = NotScalarExpr->getSourceRange(); | |||
3828 | } | |||
3829 | } else { | |||
3830 | ErrorFound = NotAnAssignmentOp; | |||
3831 | ErrorLoc = AtomicBody->getExprLoc(); | |||
3832 | ErrorRange = AtomicBody->getSourceRange(); | |||
3833 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | |||
3834 | : AtomicBody->getExprLoc(); | |||
3835 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | |||
3836 | : AtomicBody->getSourceRange(); | |||
3837 | } | |||
3838 | } else { | |||
3839 | ErrorFound = NotAnExpression; | |||
3840 | NoteLoc = ErrorLoc = Body->getLocStart(); | |||
3841 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | |||
3842 | } | |||
3843 | if (ErrorFound != NoError) { | |||
3844 | Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) | |||
3845 | << ErrorRange; | |||
3846 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | |||
3847 | << NoteRange; | |||
3848 | return StmtError(); | |||
3849 | } else if (CurContext->isDependentContext()) | |||
3850 | V = X = nullptr; | |||
3851 | } else if (AtomicKind == OMPC_write) { | |||
3852 | enum { | |||
3853 | NotAnExpression, | |||
3854 | NotAnAssignmentOp, | |||
3855 | NotAScalarType, | |||
3856 | NotAnLValue, | |||
3857 | NoError | |||
3858 | } ErrorFound = NoError; | |||
3859 | SourceLocation ErrorLoc, NoteLoc; | |||
3860 | SourceRange ErrorRange, NoteRange; | |||
3861 | // If clause is write: | |||
3862 | // x = expr; | |||
3863 | if (auto AtomicBody = dyn_cast<Expr>(Body)) { | |||
3864 | auto AtomicBinOp = | |||
3865 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | |||
3866 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | |||
3867 | X = AtomicBinOp->getLHS(); | |||
3868 | E = AtomicBinOp->getRHS(); | |||
3869 | if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && | |||
3870 | (E->isInstantiationDependent() || E->getType()->isScalarType())) { | |||
3871 | if (!X->isLValue()) { | |||
3872 | ErrorFound = NotAnLValue; | |||
3873 | ErrorLoc = AtomicBinOp->getExprLoc(); | |||
3874 | ErrorRange = AtomicBinOp->getSourceRange(); | |||
3875 | NoteLoc = X->getExprLoc(); | |||
3876 | NoteRange = X->getSourceRange(); | |||
3877 | } | |||
3878 | } else if (!X->isInstantiationDependent() || | |||
3879 | !E->isInstantiationDependent()) { | |||
3880 | auto NotScalarExpr = | |||
3881 | (X->isInstantiationDependent() || X->getType()->isScalarType()) | |||
3882 | ? E | |||
3883 | : X; | |||
3884 | ErrorFound = NotAScalarType; | |||
3885 | ErrorLoc = AtomicBinOp->getExprLoc(); | |||
3886 | ErrorRange = AtomicBinOp->getSourceRange(); | |||
3887 | NoteLoc = NotScalarExpr->getExprLoc(); | |||
3888 | NoteRange = NotScalarExpr->getSourceRange(); | |||
3889 | } | |||
3890 | } else { | |||
3891 | ErrorFound = NotAnAssignmentOp; | |||
3892 | ErrorLoc = AtomicBody->getExprLoc(); | |||
3893 | ErrorRange = AtomicBody->getSourceRange(); | |||
3894 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | |||
3895 | : AtomicBody->getExprLoc(); | |||
3896 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | |||
3897 | : AtomicBody->getSourceRange(); | |||
3898 | } | |||
3899 | } else { | |||
3900 | ErrorFound = NotAnExpression; | |||
3901 | NoteLoc = ErrorLoc = Body->getLocStart(); | |||
3902 | NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); | |||
3903 | } | |||
3904 | if (ErrorFound != NoError) { | |||
3905 | Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) | |||
3906 | << ErrorRange; | |||
3907 | Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound | |||
3908 | << NoteRange; | |||
3909 | return StmtError(); | |||
3910 | } else if (CurContext->isDependentContext()) | |||
3911 | E = X = nullptr; | |||
3912 | } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { | |||
3913 | // If clause is update: | |||
3914 | // x++; | |||
3915 | // x--; | |||
3916 | // ++x; | |||
3917 | // --x; | |||
3918 | // x binop= expr; | |||
3919 | // x = x binop expr; | |||
3920 | // x = expr binop x; | |||
3921 | OpenMPAtomicUpdateChecker Checker(*this); | |||
3922 | if (Checker.checkStatement( | |||
3923 | Body, (AtomicKind == OMPC_update) | |||
3924 | ? diag::err_omp_atomic_update_not_expression_statement | |||
3925 | : diag::err_omp_atomic_not_expression_statement, | |||
3926 | diag::note_omp_atomic_update)) | |||
3927 | return StmtError(); | |||
3928 | if (!CurContext->isDependentContext()) { | |||
3929 | E = Checker.getExpr(); | |||
3930 | X = Checker.getX(); | |||
3931 | UE = Checker.getUpdateExpr(); | |||
3932 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | |||
3933 | } | |||
3934 | } else if (AtomicKind == OMPC_capture) { | |||
3935 | enum { | |||
3936 | NotAnAssignmentOp, | |||
3937 | NotACompoundStatement, | |||
3938 | NotTwoSubstatements, | |||
3939 | NotASpecificExpression, | |||
3940 | NoError | |||
3941 | } ErrorFound = NoError; | |||
3942 | SourceLocation ErrorLoc, NoteLoc; | |||
3943 | SourceRange ErrorRange, NoteRange; | |||
3944 | if (auto *AtomicBody = dyn_cast<Expr>(Body)) { | |||
3945 | // If clause is a capture: | |||
3946 | // v = x++; | |||
3947 | // v = x--; | |||
3948 | // v = ++x; | |||
3949 | // v = --x; | |||
3950 | // v = x binop= expr; | |||
3951 | // v = x = x binop expr; | |||
3952 | // v = x = expr binop x; | |||
3953 | auto *AtomicBinOp = | |||
3954 | dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); | |||
3955 | if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { | |||
3956 | V = AtomicBinOp->getLHS(); | |||
3957 | Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); | |||
3958 | OpenMPAtomicUpdateChecker Checker(*this); | |||
3959 | if (Checker.checkStatement( | |||
3960 | Body, diag::err_omp_atomic_capture_not_expression_statement, | |||
3961 | diag::note_omp_atomic_update)) | |||
3962 | return StmtError(); | |||
3963 | E = Checker.getExpr(); | |||
3964 | X = Checker.getX(); | |||
3965 | UE = Checker.getUpdateExpr(); | |||
3966 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | |||
3967 | IsPostfixUpdate = Checker.isPostfixUpdate(); | |||
3968 | } else { | |||
3969 | ErrorLoc = AtomicBody->getExprLoc(); | |||
3970 | ErrorRange = AtomicBody->getSourceRange(); | |||
3971 | NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() | |||
3972 | : AtomicBody->getExprLoc(); | |||
3973 | NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() | |||
3974 | : AtomicBody->getSourceRange(); | |||
3975 | ErrorFound = NotAnAssignmentOp; | |||
3976 | } | |||
3977 | if (ErrorFound != NoError) { | |||
3978 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) | |||
3979 | << ErrorRange; | |||
3980 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | |||
3981 | return StmtError(); | |||
3982 | } else if (CurContext->isDependentContext()) { | |||
3983 | UE = V = E = X = nullptr; | |||
3984 | } | |||
3985 | } else { | |||
3986 | // If clause is a capture: | |||
3987 | // { v = x; x = expr; } | |||
3988 | // { v = x; x++; } | |||
3989 | // { v = x; x--; } | |||
3990 | // { v = x; ++x; } | |||
3991 | // { v = x; --x; } | |||
3992 | // { v = x; x binop= expr; } | |||
3993 | // { v = x; x = x binop expr; } | |||
3994 | // { v = x; x = expr binop x; } | |||
3995 | // { x++; v = x; } | |||
3996 | // { x--; v = x; } | |||
3997 | // { ++x; v = x; } | |||
3998 | // { --x; v = x; } | |||
3999 | // { x binop= expr; v = x; } | |||
4000 | // { x = x binop expr; v = x; } | |||
4001 | // { x = expr binop x; v = x; } | |||
4002 | if (auto *CS = dyn_cast<CompoundStmt>(Body)) { | |||
4003 | // Check that this is { expr1; expr2; } | |||
4004 | if (CS->size() == 2) { | |||
4005 | auto *First = CS->body_front(); | |||
4006 | auto *Second = CS->body_back(); | |||
4007 | if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) | |||
4008 | First = EWC->getSubExpr()->IgnoreParenImpCasts(); | |||
4009 | if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) | |||
4010 | Second = EWC->getSubExpr()->IgnoreParenImpCasts(); | |||
4011 | // Need to find what subexpression is 'v' and what is 'x'. | |||
4012 | OpenMPAtomicUpdateChecker Checker(*this); | |||
4013 | bool IsUpdateExprFound = !Checker.checkStatement(Second); | |||
4014 | BinaryOperator *BinOp = nullptr; | |||
4015 | if (IsUpdateExprFound) { | |||
4016 | BinOp = dyn_cast<BinaryOperator>(First); | |||
4017 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | |||
4018 | } | |||
4019 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | |||
4020 | // { v = x; x++; } | |||
4021 | // { v = x; x--; } | |||
4022 | // { v = x; ++x; } | |||
4023 | // { v = x; --x; } | |||
4024 | // { v = x; x binop= expr; } | |||
4025 | // { v = x; x = x binop expr; } | |||
4026 | // { v = x; x = expr binop x; } | |||
4027 | // Check that the first expression has form v = x. | |||
4028 | auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | |||
4029 | llvm::FoldingSetNodeID XId, PossibleXId; | |||
4030 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | |||
4031 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | |||
4032 | IsUpdateExprFound = XId == PossibleXId; | |||
4033 | if (IsUpdateExprFound) { | |||
4034 | V = BinOp->getLHS(); | |||
4035 | X = Checker.getX(); | |||
4036 | E = Checker.getExpr(); | |||
4037 | UE = Checker.getUpdateExpr(); | |||
4038 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | |||
4039 | IsPostfixUpdate = true; | |||
4040 | } | |||
4041 | } | |||
4042 | if (!IsUpdateExprFound) { | |||
4043 | IsUpdateExprFound = !Checker.checkStatement(First); | |||
4044 | BinOp = nullptr; | |||
4045 | if (IsUpdateExprFound) { | |||
4046 | BinOp = dyn_cast<BinaryOperator>(Second); | |||
4047 | IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; | |||
4048 | } | |||
4049 | if (IsUpdateExprFound && !CurContext->isDependentContext()) { | |||
4050 | // { x++; v = x; } | |||
4051 | // { x--; v = x; } | |||
4052 | // { ++x; v = x; } | |||
4053 | // { --x; v = x; } | |||
4054 | // { x binop= expr; v = x; } | |||
4055 | // { x = x binop expr; v = x; } | |||
4056 | // { x = expr binop x; v = x; } | |||
4057 | // Check that the second expression has form v = x. | |||
4058 | auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); | |||
4059 | llvm::FoldingSetNodeID XId, PossibleXId; | |||
4060 | Checker.getX()->Profile(XId, Context, /*Canonical=*/true); | |||
4061 | PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); | |||
4062 | IsUpdateExprFound = XId == PossibleXId; | |||
4063 | if (IsUpdateExprFound) { | |||
4064 | V = BinOp->getLHS(); | |||
4065 | X = Checker.getX(); | |||
4066 | E = Checker.getExpr(); | |||
4067 | UE = Checker.getUpdateExpr(); | |||
4068 | IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); | |||
4069 | IsPostfixUpdate = false; | |||
4070 | } | |||
4071 | } | |||
4072 | } | |||
4073 | if (!IsUpdateExprFound) { | |||
4074 | // { v = x; x = expr; } | |||
4075 | auto *FirstBinOp = dyn_cast<BinaryOperator>(First); | |||
4076 | if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { | |||
4077 | ErrorFound = NotAnAssignmentOp; | |||
4078 | NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() | |||
4079 | : First->getLocStart(); | |||
4080 | NoteRange = ErrorRange = FirstBinOp | |||
4081 | ? FirstBinOp->getSourceRange() | |||
4082 | : SourceRange(ErrorLoc, ErrorLoc); | |||
4083 | } else { | |||
4084 | auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); | |||
4085 | if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { | |||
4086 | ErrorFound = NotAnAssignmentOp; | |||
4087 | NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc() | |||
4088 | : Second->getLocStart(); | |||
4089 | NoteRange = ErrorRange = SecondBinOp | |||
4090 | ? SecondBinOp->getSourceRange() | |||
4091 | : SourceRange(ErrorLoc, ErrorLoc); | |||
4092 | } else { | |||
4093 | auto *PossibleXRHSInFirst = | |||
4094 | FirstBinOp->getRHS()->IgnoreParenImpCasts(); | |||
4095 | auto *PossibleXLHSInSecond = | |||
4096 | SecondBinOp->getLHS()->IgnoreParenImpCasts(); | |||
4097 | llvm::FoldingSetNodeID X1Id, X2Id; | |||
4098 | PossibleXRHSInFirst->Profile(X1Id, Context, /*Canonical=*/true); | |||
4099 | PossibleXLHSInSecond->Profile(X2Id, Context, | |||
4100 | /*Canonical=*/true); | |||
4101 | IsUpdateExprFound = X1Id == X2Id; | |||
4102 | if (IsUpdateExprFound) { | |||
4103 | V = FirstBinOp->getLHS(); | |||
4104 | X = SecondBinOp->getLHS(); | |||
4105 | E = SecondBinOp->getRHS(); | |||
4106 | UE = nullptr; | |||
4107 | IsXLHSInRHSPart = false; | |||
4108 | IsPostfixUpdate = true; | |||
4109 | } else { | |||
4110 | ErrorFound = NotASpecificExpression; | |||
4111 | ErrorLoc = FirstBinOp->getExprLoc(); | |||
4112 | ErrorRange = FirstBinOp->getSourceRange(); | |||
4113 | NoteLoc = SecondBinOp->getLHS()->getExprLoc(); | |||
4114 | NoteRange = SecondBinOp->getRHS()->getSourceRange(); | |||
4115 | } | |||
4116 | } | |||
4117 | } | |||
4118 | } | |||
4119 | } else { | |||
4120 | NoteLoc = ErrorLoc = Body->getLocStart(); | |||
4121 | NoteRange = ErrorRange = | |||
4122 | SourceRange(Body->getLocStart(), Body->getLocStart()); | |||
4123 | ErrorFound = NotTwoSubstatements; | |||
4124 | } | |||
4125 | } else { | |||
4126 | NoteLoc = ErrorLoc = Body->getLocStart(); | |||
4127 | NoteRange = ErrorRange = | |||
4128 | SourceRange(Body->getLocStart(), Body->getLocStart()); | |||
4129 | ErrorFound = NotACompoundStatement; | |||
4130 | } | |||
4131 | if (ErrorFound != NoError) { | |||
4132 | Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) | |||
4133 | << ErrorRange; | |||
4134 | Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; | |||
4135 | return StmtError(); | |||
4136 | } else if (CurContext->isDependentContext()) { | |||
4137 | UE = V = E = X = nullptr; | |||
4138 | } | |||
4139 | } | |||
4140 | } | |||
4141 | ||||
4142 | getCurFunction()->setHasBranchProtectedScope(); | |||
4143 | ||||
4144 | return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, | |||
4145 | X, V, E, UE, IsXLHSInRHSPart, | |||
4146 | IsPostfixUpdate); | |||
4147 | } | |||
4148 | ||||
4149 | StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, | |||
4150 | Stmt *AStmt, | |||
4151 | SourceLocation StartLoc, | |||
4152 | SourceLocation EndLoc) { | |||
4153 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4153, __PRETTY_FUNCTION__)); | |||
4154 | ||||
4155 | // OpenMP [2.16, Nesting of Regions] | |||
4156 | // If specified, a teams construct must be contained within a target | |||
4157 | // construct. That target construct must contain no statements or directives | |||
4158 | // outside of the teams construct. | |||
4159 | if (DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnerTeamsRegion()) { | |||
4160 | auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); | |||
4161 | bool OMPTeamsFound = true; | |||
4162 | if (auto *CS = dyn_cast<CompoundStmt>(S)) { | |||
4163 | auto I = CS->body_begin(); | |||
4164 | while (I != CS->body_end()) { | |||
4165 | auto OED = dyn_cast<OMPExecutableDirective>(*I); | |||
4166 | if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { | |||
4167 | OMPTeamsFound = false; | |||
4168 | break; | |||
4169 | } | |||
4170 | ++I; | |||
4171 | } | |||
4172 | assert(I != CS->body_end() && "Not found statement")((I != CS->body_end() && "Not found statement") ? static_cast <void> (0) : __assert_fail ("I != CS->body_end() && \"Not found statement\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4172, __PRETTY_FUNCTION__)); | |||
4173 | S = *I; | |||
4174 | } | |||
4175 | if (!OMPTeamsFound) { | |||
4176 | Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); | |||
4177 | Diag(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getInnerTeamsRegionLoc(), | |||
4178 | diag::note_omp_nested_teams_construct_here); | |||
4179 | Diag(S->getLocStart(), diag::note_omp_nested_statement_here) | |||
4180 | << isa<OMPExecutableDirective>(S); | |||
4181 | return StmtError(); | |||
4182 | } | |||
4183 | } | |||
4184 | ||||
4185 | getCurFunction()->setHasBranchProtectedScope(); | |||
4186 | ||||
4187 | return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | |||
4188 | } | |||
4189 | ||||
4190 | StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, | |||
4191 | Stmt *AStmt, SourceLocation StartLoc, | |||
4192 | SourceLocation EndLoc) { | |||
4193 | assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected")((AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected" ) ? static_cast<void> (0) : __assert_fail ("AStmt && isa<CapturedStmt>(AStmt) && \"Captured statement expected\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4193, __PRETTY_FUNCTION__)); | |||
4194 | CapturedStmt *CS = cast<CapturedStmt>(AStmt); | |||
4195 | // 1.2.2 OpenMP Language Terminology | |||
4196 | // Structured block - An executable statement with a single entry at the | |||
4197 | // top and a single exit at the bottom. | |||
4198 | // The point of exit cannot be a branch out of the structured block. | |||
4199 | // longjmp() and throw() must not violate the entry/exit criteria. | |||
4200 | CS->getCapturedDecl()->setNothrow(); | |||
4201 | ||||
4202 | getCurFunction()->setHasBranchProtectedScope(); | |||
4203 | ||||
4204 | return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); | |||
4205 | } | |||
4206 | ||||
4207 | OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, | |||
4208 | SourceLocation StartLoc, | |||
4209 | SourceLocation LParenLoc, | |||
4210 | SourceLocation EndLoc) { | |||
4211 | OMPClause *Res = nullptr; | |||
4212 | switch (Kind) { | |||
4213 | case OMPC_if: | |||
4214 | Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); | |||
4215 | break; | |||
4216 | case OMPC_final: | |||
4217 | Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); | |||
4218 | break; | |||
4219 | case OMPC_num_threads: | |||
4220 | Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); | |||
4221 | break; | |||
4222 | case OMPC_safelen: | |||
4223 | Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); | |||
4224 | break; | |||
4225 | case OMPC_collapse: | |||
4226 | Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); | |||
4227 | break; | |||
4228 | case OMPC_default: | |||
4229 | case OMPC_proc_bind: | |||
4230 | case OMPC_schedule: | |||
4231 | case OMPC_private: | |||
4232 | case OMPC_firstprivate: | |||
4233 | case OMPC_lastprivate: | |||
4234 | case OMPC_shared: | |||
4235 | case OMPC_reduction: | |||
4236 | case OMPC_linear: | |||
4237 | case OMPC_aligned: | |||
4238 | case OMPC_copyin: | |||
4239 | case OMPC_copyprivate: | |||
4240 | case OMPC_ordered: | |||
4241 | case OMPC_nowait: | |||
4242 | case OMPC_untied: | |||
4243 | case OMPC_mergeable: | |||
4244 | case OMPC_threadprivate: | |||
4245 | case OMPC_flush: | |||
4246 | case OMPC_read: | |||
4247 | case OMPC_write: | |||
4248 | case OMPC_update: | |||
4249 | case OMPC_capture: | |||
4250 | case OMPC_seq_cst: | |||
4251 | case OMPC_depend: | |||
4252 | case OMPC_unknown: | |||
4253 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4253); | |||
4254 | } | |||
4255 | return Res; | |||
4256 | } | |||
4257 | ||||
4258 | OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, | |||
4259 | SourceLocation LParenLoc, | |||
4260 | SourceLocation EndLoc) { | |||
4261 | Expr *ValExpr = Condition; | |||
4262 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | |||
4263 | !Condition->isInstantiationDependent() && | |||
4264 | !Condition->containsUnexpandedParameterPack()) { | |||
4265 | ExprResult Val = ActOnBooleanCondition(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), | |||
4266 | Condition->getExprLoc(), Condition); | |||
4267 | if (Val.isInvalid()) | |||
4268 | return nullptr; | |||
4269 | ||||
4270 | ValExpr = Val.get(); | |||
4271 | } | |||
4272 | ||||
4273 | return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); | |||
4274 | } | |||
4275 | ||||
4276 | OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, | |||
4277 | SourceLocation StartLoc, | |||
4278 | SourceLocation LParenLoc, | |||
4279 | SourceLocation EndLoc) { | |||
4280 | Expr *ValExpr = Condition; | |||
4281 | if (!Condition->isValueDependent() && !Condition->isTypeDependent() && | |||
4282 | !Condition->isInstantiationDependent() && | |||
4283 | !Condition->containsUnexpandedParameterPack()) { | |||
4284 | ExprResult Val = ActOnBooleanCondition(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), | |||
4285 | Condition->getExprLoc(), Condition); | |||
4286 | if (Val.isInvalid()) | |||
4287 | return nullptr; | |||
4288 | ||||
4289 | ValExpr = Val.get(); | |||
4290 | } | |||
4291 | ||||
4292 | return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); | |||
4293 | } | |||
4294 | ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, | |||
4295 | Expr *Op) { | |||
4296 | if (!Op) | |||
4297 | return ExprError(); | |||
4298 | ||||
4299 | class IntConvertDiagnoser : public ICEConvertDiagnoser { | |||
4300 | public: | |||
4301 | IntConvertDiagnoser() | |||
4302 | : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} | |||
4303 | SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, | |||
4304 | QualType T) override { | |||
4305 | return S.Diag(Loc, diag::err_omp_not_integral) << T; | |||
4306 | } | |||
4307 | SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, | |||
4308 | QualType T) override { | |||
4309 | return S.Diag(Loc, diag::err_omp_incomplete_type) << T; | |||
4310 | } | |||
4311 | SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, | |||
4312 | QualType T, | |||
4313 | QualType ConvTy) override { | |||
4314 | return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; | |||
4315 | } | |||
4316 | SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, | |||
4317 | QualType ConvTy) override { | |||
4318 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | |||
4319 | << ConvTy->isEnumeralType() << ConvTy; | |||
4320 | } | |||
4321 | SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, | |||
4322 | QualType T) override { | |||
4323 | return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; | |||
4324 | } | |||
4325 | SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, | |||
4326 | QualType ConvTy) override { | |||
4327 | return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) | |||
4328 | << ConvTy->isEnumeralType() << ConvTy; | |||
4329 | } | |||
4330 | SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, | |||
4331 | QualType) override { | |||
4332 | llvm_unreachable("conversion functions are permitted")::llvm::llvm_unreachable_internal("conversion functions are permitted" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4332); | |||
4333 | } | |||
4334 | } ConvertDiagnoser; | |||
4335 | return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); | |||
4336 | } | |||
4337 | ||||
4338 | OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, | |||
4339 | SourceLocation StartLoc, | |||
4340 | SourceLocation LParenLoc, | |||
4341 | SourceLocation EndLoc) { | |||
4342 | Expr *ValExpr = NumThreads; | |||
4343 | if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() && | |||
4344 | !NumThreads->containsUnexpandedParameterPack()) { | |||
4345 | SourceLocation NumThreadsLoc = NumThreads->getLocStart(); | |||
4346 | ExprResult Val = | |||
4347 | PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads); | |||
4348 | if (Val.isInvalid()) | |||
4349 | return nullptr; | |||
4350 | ||||
4351 | ValExpr = Val.get(); | |||
4352 | ||||
4353 | // OpenMP [2.5, Restrictions] | |||
4354 | // The num_threads expression must evaluate to a positive integer value. | |||
4355 | llvm::APSInt Result; | |||
4356 | if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() && | |||
4357 | !Result.isStrictlyPositive()) { | |||
4358 | Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause) | |||
4359 | << "num_threads" << NumThreads->getSourceRange(); | |||
4360 | return nullptr; | |||
4361 | } | |||
4362 | } | |||
4363 | ||||
4364 | return new (Context) | |||
4365 | OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); | |||
4366 | } | |||
4367 | ||||
4368 | ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, | |||
4369 | OpenMPClauseKind CKind) { | |||
4370 | if (!E) | |||
4371 | return ExprError(); | |||
4372 | if (E->isValueDependent() || E->isTypeDependent() || | |||
4373 | E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) | |||
4374 | return E; | |||
4375 | llvm::APSInt Result; | |||
4376 | ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); | |||
4377 | if (ICE.isInvalid()) | |||
4378 | return ExprError(); | |||
4379 | if (!Result.isStrictlyPositive()) { | |||
4380 | Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) | |||
4381 | << getOpenMPClauseName(CKind) << E->getSourceRange(); | |||
4382 | return ExprError(); | |||
4383 | } | |||
4384 | if (CKind == OMPC_aligned && !Result.isPowerOf2()) { | |||
4385 | Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) | |||
4386 | << E->getSourceRange(); | |||
4387 | return ExprError(); | |||
4388 | } | |||
4389 | if (CKind == OMPC_collapse) { | |||
4390 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setCollapseNumber(Result.getExtValue()); | |||
4391 | } | |||
4392 | return ICE; | |||
4393 | } | |||
4394 | ||||
4395 | OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, | |||
4396 | SourceLocation LParenLoc, | |||
4397 | SourceLocation EndLoc) { | |||
4398 | // OpenMP [2.8.1, simd construct, Description] | |||
4399 | // The parameter of the safelen clause must be a constant | |||
4400 | // positive integer expression. | |||
4401 | ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); | |||
4402 | if (Safelen.isInvalid()) | |||
4403 | return nullptr; | |||
4404 | return new (Context) | |||
4405 | OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); | |||
4406 | } | |||
4407 | ||||
4408 | OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, | |||
4409 | SourceLocation StartLoc, | |||
4410 | SourceLocation LParenLoc, | |||
4411 | SourceLocation EndLoc) { | |||
4412 | // OpenMP [2.7.1, loop construct, Description] | |||
4413 | // OpenMP [2.8.1, simd construct, Description] | |||
4414 | // OpenMP [2.9.6, distribute construct, Description] | |||
4415 | // The parameter of the collapse clause must be a constant | |||
4416 | // positive integer expression. | |||
4417 | ExprResult NumForLoopsResult = | |||
4418 | VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); | |||
4419 | if (NumForLoopsResult.isInvalid()) | |||
4420 | return nullptr; | |||
4421 | return new (Context) | |||
4422 | OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); | |||
4423 | } | |||
4424 | ||||
4425 | OMPClause *Sema::ActOnOpenMPSimpleClause( | |||
4426 | OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, | |||
4427 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { | |||
4428 | OMPClause *Res = nullptr; | |||
4429 | switch (Kind) { | |||
4430 | case OMPC_default: | |||
4431 | Res = | |||
4432 | ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), | |||
4433 | ArgumentLoc, StartLoc, LParenLoc, EndLoc); | |||
4434 | break; | |||
4435 | case OMPC_proc_bind: | |||
4436 | Res = ActOnOpenMPProcBindClause( | |||
4437 | static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, | |||
4438 | LParenLoc, EndLoc); | |||
4439 | break; | |||
4440 | case OMPC_if: | |||
4441 | case OMPC_final: | |||
4442 | case OMPC_num_threads: | |||
4443 | case OMPC_safelen: | |||
4444 | case OMPC_collapse: | |||
4445 | case OMPC_schedule: | |||
4446 | case OMPC_private: | |||
4447 | case OMPC_firstprivate: | |||
4448 | case OMPC_lastprivate: | |||
4449 | case OMPC_shared: | |||
4450 | case OMPC_reduction: | |||
4451 | case OMPC_linear: | |||
4452 | case OMPC_aligned: | |||
4453 | case OMPC_copyin: | |||
4454 | case OMPC_copyprivate: | |||
4455 | case OMPC_ordered: | |||
4456 | case OMPC_nowait: | |||
4457 | case OMPC_untied: | |||
4458 | case OMPC_mergeable: | |||
4459 | case OMPC_threadprivate: | |||
4460 | case OMPC_flush: | |||
4461 | case OMPC_read: | |||
4462 | case OMPC_write: | |||
4463 | case OMPC_update: | |||
4464 | case OMPC_capture: | |||
4465 | case OMPC_seq_cst: | |||
4466 | case OMPC_depend: | |||
4467 | case OMPC_unknown: | |||
4468 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4468); | |||
4469 | } | |||
4470 | return Res; | |||
4471 | } | |||
4472 | ||||
4473 | OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, | |||
4474 | SourceLocation KindKwLoc, | |||
4475 | SourceLocation StartLoc, | |||
4476 | SourceLocation LParenLoc, | |||
4477 | SourceLocation EndLoc) { | |||
4478 | if (Kind == OMPC_DEFAULT_unknown) { | |||
4479 | std::string Values; | |||
4480 | static_assert(OMPC_DEFAULT_unknown > 0, | |||
4481 | "OMPC_DEFAULT_unknown not greater than 0"); | |||
4482 | std::string Sep(", "); | |||
4483 | for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) { | |||
4484 | Values += "'"; | |||
4485 | Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); | |||
4486 | Values += "'"; | |||
4487 | switch (i) { | |||
4488 | case OMPC_DEFAULT_unknown - 2: | |||
4489 | Values += " or "; | |||
4490 | break; | |||
4491 | case OMPC_DEFAULT_unknown - 1: | |||
4492 | break; | |||
4493 | default: | |||
4494 | Values += Sep; | |||
4495 | break; | |||
4496 | } | |||
4497 | } | |||
4498 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | |||
4499 | << Values << getOpenMPClauseName(OMPC_default); | |||
4500 | return nullptr; | |||
4501 | } | |||
4502 | switch (Kind) { | |||
4503 | case OMPC_DEFAULT_none: | |||
4504 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSANone(KindKwLoc); | |||
4505 | break; | |||
4506 | case OMPC_DEFAULT_shared: | |||
4507 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setDefaultDSAShared(KindKwLoc); | |||
4508 | break; | |||
4509 | case OMPC_DEFAULT_unknown: | |||
4510 | llvm_unreachable("Clause kind is not allowed.")::llvm::llvm_unreachable_internal("Clause kind is not allowed." , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4510); | |||
4511 | break; | |||
4512 | } | |||
4513 | return new (Context) | |||
4514 | OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | |||
4515 | } | |||
4516 | ||||
4517 | OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, | |||
4518 | SourceLocation KindKwLoc, | |||
4519 | SourceLocation StartLoc, | |||
4520 | SourceLocation LParenLoc, | |||
4521 | SourceLocation EndLoc) { | |||
4522 | if (Kind == OMPC_PROC_BIND_unknown) { | |||
4523 | std::string Values; | |||
4524 | std::string Sep(", "); | |||
4525 | for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) { | |||
4526 | Values += "'"; | |||
4527 | Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i); | |||
4528 | Values += "'"; | |||
4529 | switch (i) { | |||
4530 | case OMPC_PROC_BIND_unknown - 2: | |||
4531 | Values += " or "; | |||
4532 | break; | |||
4533 | case OMPC_PROC_BIND_unknown - 1: | |||
4534 | break; | |||
4535 | default: | |||
4536 | Values += Sep; | |||
4537 | break; | |||
4538 | } | |||
4539 | } | |||
4540 | Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) | |||
4541 | << Values << getOpenMPClauseName(OMPC_proc_bind); | |||
4542 | return nullptr; | |||
4543 | } | |||
4544 | return new (Context) | |||
4545 | OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); | |||
4546 | } | |||
4547 | ||||
4548 | OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( | |||
4549 | OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, | |||
4550 | SourceLocation StartLoc, SourceLocation LParenLoc, | |||
4551 | SourceLocation ArgumentLoc, SourceLocation CommaLoc, | |||
4552 | SourceLocation EndLoc) { | |||
4553 | OMPClause *Res = nullptr; | |||
4554 | switch (Kind) { | |||
4555 | case OMPC_schedule: | |||
4556 | Res = ActOnOpenMPScheduleClause( | |||
4557 | static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, | |||
4558 | LParenLoc, ArgumentLoc, CommaLoc, EndLoc); | |||
4559 | break; | |||
4560 | case OMPC_if: | |||
4561 | case OMPC_final: | |||
4562 | case OMPC_num_threads: | |||
4563 | case OMPC_safelen: | |||
4564 | case OMPC_collapse: | |||
4565 | case OMPC_default: | |||
4566 | case OMPC_proc_bind: | |||
4567 | case OMPC_private: | |||
4568 | case OMPC_firstprivate: | |||
4569 | case OMPC_lastprivate: | |||
4570 | case OMPC_shared: | |||
4571 | case OMPC_reduction: | |||
4572 | case OMPC_linear: | |||
4573 | case OMPC_aligned: | |||
4574 | case OMPC_copyin: | |||
4575 | case OMPC_copyprivate: | |||
4576 | case OMPC_ordered: | |||
4577 | case OMPC_nowait: | |||
4578 | case OMPC_untied: | |||
4579 | case OMPC_mergeable: | |||
4580 | case OMPC_threadprivate: | |||
4581 | case OMPC_flush: | |||
4582 | case OMPC_read: | |||
4583 | case OMPC_write: | |||
4584 | case OMPC_update: | |||
4585 | case OMPC_capture: | |||
4586 | case OMPC_seq_cst: | |||
4587 | case OMPC_depend: | |||
4588 | case OMPC_unknown: | |||
4589 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4589); | |||
4590 | } | |||
4591 | return Res; | |||
4592 | } | |||
4593 | ||||
4594 | OMPClause *Sema::ActOnOpenMPScheduleClause( | |||
4595 | OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, | |||
4596 | SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, | |||
4597 | SourceLocation EndLoc) { | |||
4598 | if (Kind == OMPC_SCHEDULE_unknown) { | |||
4599 | std::string Values; | |||
4600 | std::string Sep(", "); | |||
4601 | for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) { | |||
4602 | Values += "'"; | |||
4603 | Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i); | |||
4604 | Values += "'"; | |||
4605 | switch (i) { | |||
4606 | case OMPC_SCHEDULE_unknown - 2: | |||
4607 | Values += " or "; | |||
4608 | break; | |||
4609 | case OMPC_SCHEDULE_unknown - 1: | |||
4610 | break; | |||
4611 | default: | |||
4612 | Values += Sep; | |||
4613 | break; | |||
4614 | } | |||
4615 | } | |||
4616 | Diag(KindLoc, diag::err_omp_unexpected_clause_value) | |||
4617 | << Values << getOpenMPClauseName(OMPC_schedule); | |||
4618 | return nullptr; | |||
4619 | } | |||
4620 | Expr *ValExpr = ChunkSize; | |||
4621 | Expr *HelperValExpr = nullptr; | |||
4622 | if (ChunkSize) { | |||
4623 | if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && | |||
4624 | !ChunkSize->isInstantiationDependent() && | |||
4625 | !ChunkSize->containsUnexpandedParameterPack()) { | |||
4626 | SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); | |||
4627 | ExprResult Val = | |||
4628 | PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); | |||
4629 | if (Val.isInvalid()) | |||
4630 | return nullptr; | |||
4631 | ||||
4632 | ValExpr = Val.get(); | |||
4633 | ||||
4634 | // OpenMP [2.7.1, Restrictions] | |||
4635 | // chunk_size must be a loop invariant integer expression with a positive | |||
4636 | // value. | |||
4637 | llvm::APSInt Result; | |||
4638 | if (ValExpr->isIntegerConstantExpr(Result, Context)) { | |||
4639 | if (Result.isSigned() && !Result.isStrictlyPositive()) { | |||
4640 | Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) | |||
4641 | << "schedule" << ChunkSize->getSourceRange(); | |||
4642 | return nullptr; | |||
4643 | } | |||
4644 | } else if (isParallelOrTaskRegion(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective())) { | |||
4645 | auto *ImpVar = buildVarDecl(*this, ChunkSize->getExprLoc(), | |||
4646 | ChunkSize->getType(), ".chunk."); | |||
4647 | auto *ImpVarRef = buildDeclRefExpr(*this, ImpVar, ChunkSize->getType(), | |||
4648 | ChunkSize->getExprLoc(), | |||
4649 | /*RefersToCapture=*/true); | |||
4650 | HelperValExpr = ImpVarRef; | |||
4651 | } | |||
4652 | } | |||
4653 | } | |||
4654 | ||||
4655 | return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, | |||
4656 | EndLoc, Kind, ValExpr, HelperValExpr); | |||
4657 | } | |||
4658 | ||||
4659 | OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, | |||
4660 | SourceLocation StartLoc, | |||
4661 | SourceLocation EndLoc) { | |||
4662 | OMPClause *Res = nullptr; | |||
4663 | switch (Kind) { | |||
4664 | case OMPC_ordered: | |||
4665 | Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); | |||
4666 | break; | |||
4667 | case OMPC_nowait: | |||
4668 | Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); | |||
4669 | break; | |||
4670 | case OMPC_untied: | |||
4671 | Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); | |||
4672 | break; | |||
4673 | case OMPC_mergeable: | |||
4674 | Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); | |||
4675 | break; | |||
4676 | case OMPC_read: | |||
4677 | Res = ActOnOpenMPReadClause(StartLoc, EndLoc); | |||
4678 | break; | |||
4679 | case OMPC_write: | |||
4680 | Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); | |||
4681 | break; | |||
4682 | case OMPC_update: | |||
4683 | Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); | |||
4684 | break; | |||
4685 | case OMPC_capture: | |||
4686 | Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); | |||
4687 | break; | |||
4688 | case OMPC_seq_cst: | |||
4689 | Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); | |||
4690 | break; | |||
4691 | case OMPC_if: | |||
4692 | case OMPC_final: | |||
4693 | case OMPC_num_threads: | |||
4694 | case OMPC_safelen: | |||
4695 | case OMPC_collapse: | |||
4696 | case OMPC_schedule: | |||
4697 | case OMPC_private: | |||
4698 | case OMPC_firstprivate: | |||
4699 | case OMPC_lastprivate: | |||
4700 | case OMPC_shared: | |||
4701 | case OMPC_reduction: | |||
4702 | case OMPC_linear: | |||
4703 | case OMPC_aligned: | |||
4704 | case OMPC_copyin: | |||
4705 | case OMPC_copyprivate: | |||
4706 | case OMPC_default: | |||
4707 | case OMPC_proc_bind: | |||
4708 | case OMPC_threadprivate: | |||
4709 | case OMPC_flush: | |||
4710 | case OMPC_depend: | |||
4711 | case OMPC_unknown: | |||
4712 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4712); | |||
4713 | } | |||
4714 | return Res; | |||
4715 | } | |||
4716 | ||||
4717 | OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, | |||
4718 | SourceLocation EndLoc) { | |||
4719 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->setOrderedRegion(); | |||
4720 | return new (Context) OMPOrderedClause(StartLoc, EndLoc); | |||
4721 | } | |||
4722 | ||||
4723 | OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, | |||
4724 | SourceLocation EndLoc) { | |||
4725 | return new (Context) OMPNowaitClause(StartLoc, EndLoc); | |||
4726 | } | |||
4727 | ||||
4728 | OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, | |||
4729 | SourceLocation EndLoc) { | |||
4730 | return new (Context) OMPUntiedClause(StartLoc, EndLoc); | |||
4731 | } | |||
4732 | ||||
4733 | OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, | |||
4734 | SourceLocation EndLoc) { | |||
4735 | return new (Context) OMPMergeableClause(StartLoc, EndLoc); | |||
4736 | } | |||
4737 | ||||
4738 | OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, | |||
4739 | SourceLocation EndLoc) { | |||
4740 | return new (Context) OMPReadClause(StartLoc, EndLoc); | |||
4741 | } | |||
4742 | ||||
4743 | OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, | |||
4744 | SourceLocation EndLoc) { | |||
4745 | return new (Context) OMPWriteClause(StartLoc, EndLoc); | |||
4746 | } | |||
4747 | ||||
4748 | OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, | |||
4749 | SourceLocation EndLoc) { | |||
4750 | return new (Context) OMPUpdateClause(StartLoc, EndLoc); | |||
4751 | } | |||
4752 | ||||
4753 | OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, | |||
4754 | SourceLocation EndLoc) { | |||
4755 | return new (Context) OMPCaptureClause(StartLoc, EndLoc); | |||
4756 | } | |||
4757 | ||||
4758 | OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, | |||
4759 | SourceLocation EndLoc) { | |||
4760 | return new (Context) OMPSeqCstClause(StartLoc, EndLoc); | |||
4761 | } | |||
4762 | ||||
4763 | OMPClause *Sema::ActOnOpenMPVarListClause( | |||
4764 | OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, | |||
4765 | SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, | |||
4766 | SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, | |||
4767 | const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, | |||
4768 | SourceLocation DepLoc) { | |||
4769 | OMPClause *Res = nullptr; | |||
4770 | switch (Kind) { | |||
4771 | case OMPC_private: | |||
4772 | Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4773 | break; | |||
4774 | case OMPC_firstprivate: | |||
4775 | Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4776 | break; | |||
4777 | case OMPC_lastprivate: | |||
4778 | Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4779 | break; | |||
4780 | case OMPC_shared: | |||
4781 | Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4782 | break; | |||
4783 | case OMPC_reduction: | |||
4784 | Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, | |||
4785 | EndLoc, ReductionIdScopeSpec, ReductionId); | |||
4786 | break; | |||
4787 | case OMPC_linear: | |||
4788 | Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, | |||
4789 | ColonLoc, EndLoc); | |||
4790 | break; | |||
4791 | case OMPC_aligned: | |||
4792 | Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, | |||
4793 | ColonLoc, EndLoc); | |||
4794 | break; | |||
4795 | case OMPC_copyin: | |||
4796 | Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4797 | break; | |||
4798 | case OMPC_copyprivate: | |||
4799 | Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4800 | break; | |||
4801 | case OMPC_flush: | |||
4802 | Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); | |||
4803 | break; | |||
4804 | case OMPC_depend: | |||
4805 | Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc, | |||
4806 | LParenLoc, EndLoc); | |||
4807 | break; | |||
4808 | case OMPC_if: | |||
4809 | case OMPC_final: | |||
4810 | case OMPC_num_threads: | |||
4811 | case OMPC_safelen: | |||
4812 | case OMPC_collapse: | |||
4813 | case OMPC_default: | |||
4814 | case OMPC_proc_bind: | |||
4815 | case OMPC_schedule: | |||
4816 | case OMPC_ordered: | |||
4817 | case OMPC_nowait: | |||
4818 | case OMPC_untied: | |||
4819 | case OMPC_mergeable: | |||
4820 | case OMPC_threadprivate: | |||
4821 | case OMPC_read: | |||
4822 | case OMPC_write: | |||
4823 | case OMPC_update: | |||
4824 | case OMPC_capture: | |||
4825 | case OMPC_seq_cst: | |||
4826 | case OMPC_unknown: | |||
4827 | llvm_unreachable("Clause is not allowed.")::llvm::llvm_unreachable_internal("Clause is not allowed.", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4827); | |||
4828 | } | |||
4829 | return Res; | |||
4830 | } | |||
4831 | ||||
4832 | OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, | |||
4833 | SourceLocation StartLoc, | |||
4834 | SourceLocation LParenLoc, | |||
4835 | SourceLocation EndLoc) { | |||
4836 | SmallVector<Expr *, 8> Vars; | |||
4837 | SmallVector<Expr *, 8> PrivateCopies; | |||
4838 | for (auto &RefExpr : VarList) { | |||
4839 | assert(RefExpr && "NULL expr in OpenMP private clause.")((RefExpr && "NULL expr in OpenMP private clause.") ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP private clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4839, __PRETTY_FUNCTION__)); | |||
4840 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
4841 | // It will be analyzed later. | |||
4842 | Vars.push_back(RefExpr); | |||
4843 | PrivateCopies.push_back(nullptr); | |||
4844 | continue; | |||
4845 | } | |||
4846 | ||||
4847 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
4848 | // OpenMP [2.1, C/C++] | |||
4849 | // A list item is a variable name. | |||
4850 | // OpenMP [2.9.3.3, Restrictions, p.1] | |||
4851 | // A variable that is part of another variable (as an array or | |||
4852 | // structure element) cannot appear in a private clause. | |||
4853 | DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); | |||
4854 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
4855 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
4856 | continue; | |||
4857 | } | |||
4858 | Decl *D = DE->getDecl(); | |||
4859 | VarDecl *VD = cast<VarDecl>(D); | |||
4860 | ||||
4861 | QualType Type = VD->getType(); | |||
4862 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
4863 | // It will be analyzed later. | |||
4864 | Vars.push_back(DE); | |||
4865 | PrivateCopies.push_back(nullptr); | |||
4866 | continue; | |||
4867 | } | |||
4868 | ||||
4869 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | |||
4870 | // A variable that appears in a private clause must not have an incomplete | |||
4871 | // type or a reference type. | |||
4872 | if (RequireCompleteType(ELoc, Type, | |||
4873 | diag::err_omp_private_incomplete_type)) { | |||
4874 | continue; | |||
4875 | } | |||
4876 | if (Type->isReferenceType()) { | |||
4877 | Diag(ELoc, diag::err_omp_clause_ref_type_arg) | |||
4878 | << getOpenMPClauseName(OMPC_private) << Type; | |||
4879 | bool IsDecl = | |||
4880 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
4881 | Diag(VD->getLocation(), | |||
4882 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
4883 | << VD; | |||
4884 | continue; | |||
4885 | } | |||
4886 | ||||
4887 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
4888 | // in a Construct] | |||
4889 | // Variables with the predetermined data-sharing attributes may not be | |||
4890 | // listed in data-sharing attributes clauses, except for the cases | |||
4891 | // listed below. For these exceptions only, listing a predetermined | |||
4892 | // variable in a data-sharing attribute clause is allowed and overrides | |||
4893 | // the variable's predetermined data-sharing attributes. | |||
4894 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
4895 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { | |||
4896 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | |||
4897 | << getOpenMPClauseName(OMPC_private); | |||
4898 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
4899 | continue; | |||
4900 | } | |||
4901 | ||||
4902 | // Variably modified types are not supported for tasks. | |||
4903 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | |||
4904 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_task) { | |||
4905 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | |||
4906 | << getOpenMPClauseName(OMPC_private) << Type | |||
4907 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | |||
4908 | bool IsDecl = | |||
4909 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
4910 | Diag(VD->getLocation(), | |||
4911 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
4912 | << VD; | |||
4913 | continue; | |||
4914 | } | |||
4915 | ||||
4916 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] | |||
4917 | // A variable of class type (or array thereof) that appears in a private | |||
4918 | // clause requires an accessible, unambiguous default constructor for the | |||
4919 | // class type. | |||
4920 | // Generate helper private variable and initialize it with the default | |||
4921 | // value. The address of the original variable is replaced by the address of | |||
4922 | // the new private variable in CodeGen. This new variable is not added to | |||
4923 | // IdResolver, so the code in the OpenMP region uses original variable for | |||
4924 | // proper diagnostics. | |||
4925 | Type = Type.getUnqualifiedType(); | |||
4926 | auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName()); | |||
4927 | ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); | |||
4928 | if (VDPrivate->isInvalidDecl()) | |||
4929 | continue; | |||
4930 | auto VDPrivateRefExpr = buildDeclRefExpr( | |||
4931 | *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); | |||
4932 | ||||
4933 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_private); | |||
4934 | Vars.push_back(DE); | |||
4935 | PrivateCopies.push_back(VDPrivateRefExpr); | |||
4936 | } | |||
4937 | ||||
4938 | if (Vars.empty()) | |||
4939 | return nullptr; | |||
4940 | ||||
4941 | return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | |||
4942 | PrivateCopies); | |||
4943 | } | |||
4944 | ||||
4945 | namespace { | |||
4946 | class DiagsUninitializedSeveretyRAII { | |||
4947 | private: | |||
4948 | DiagnosticsEngine &Diags; | |||
4949 | SourceLocation SavedLoc; | |||
4950 | bool IsIgnored; | |||
4951 | ||||
4952 | public: | |||
4953 | DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, | |||
4954 | bool IsIgnored) | |||
4955 | : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { | |||
4956 | if (!IsIgnored) { | |||
4957 | Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, | |||
4958 | /*Map*/ diag::Severity::Ignored, Loc); | |||
4959 | } | |||
4960 | } | |||
4961 | ~DiagsUninitializedSeveretyRAII() { | |||
4962 | if (!IsIgnored) | |||
4963 | Diags.popMappings(SavedLoc); | |||
4964 | } | |||
4965 | }; | |||
4966 | } | |||
4967 | ||||
4968 | OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, | |||
4969 | SourceLocation StartLoc, | |||
4970 | SourceLocation LParenLoc, | |||
4971 | SourceLocation EndLoc) { | |||
4972 | SmallVector<Expr *, 8> Vars; | |||
4973 | SmallVector<Expr *, 8> PrivateCopies; | |||
4974 | SmallVector<Expr *, 8> Inits; | |||
4975 | bool IsImplicitClause = | |||
4976 | StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); | |||
4977 | auto ImplicitClauseLoc = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getConstructLoc(); | |||
4978 | ||||
4979 | for (auto &RefExpr : VarList) { | |||
4980 | assert(RefExpr && "NULL expr in OpenMP firstprivate clause.")((RefExpr && "NULL expr in OpenMP firstprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP firstprivate clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 4980, __PRETTY_FUNCTION__)); | |||
4981 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
4982 | // It will be analyzed later. | |||
4983 | Vars.push_back(RefExpr); | |||
4984 | PrivateCopies.push_back(nullptr); | |||
4985 | Inits.push_back(nullptr); | |||
4986 | continue; | |||
4987 | } | |||
4988 | ||||
4989 | SourceLocation ELoc = | |||
4990 | IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc(); | |||
4991 | // OpenMP [2.1, C/C++] | |||
4992 | // A list item is a variable name. | |||
4993 | // OpenMP [2.9.3.3, Restrictions, p.1] | |||
4994 | // A variable that is part of another variable (as an array or | |||
4995 | // structure element) cannot appear in a private clause. | |||
4996 | DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); | |||
4997 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
4998 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
4999 | continue; | |||
5000 | } | |||
5001 | Decl *D = DE->getDecl(); | |||
5002 | VarDecl *VD = cast<VarDecl>(D); | |||
5003 | ||||
5004 | QualType Type = VD->getType(); | |||
5005 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
5006 | // It will be analyzed later. | |||
5007 | Vars.push_back(DE); | |||
5008 | PrivateCopies.push_back(nullptr); | |||
5009 | Inits.push_back(nullptr); | |||
5010 | continue; | |||
5011 | } | |||
5012 | ||||
5013 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | |||
5014 | // A variable that appears in a private clause must not have an incomplete | |||
5015 | // type or a reference type. | |||
5016 | if (RequireCompleteType(ELoc, Type, | |||
5017 | diag::err_omp_firstprivate_incomplete_type)) { | |||
5018 | continue; | |||
5019 | } | |||
5020 | if (Type->isReferenceType()) { | |||
5021 | if (IsImplicitClause) { | |||
5022 | Diag(ImplicitClauseLoc, | |||
5023 | diag::err_omp_task_predetermined_firstprivate_ref_type_arg) | |||
5024 | << Type; | |||
5025 | Diag(RefExpr->getExprLoc(), diag::note_used_here); | |||
5026 | } else { | |||
5027 | Diag(ELoc, diag::err_omp_clause_ref_type_arg) | |||
5028 | << getOpenMPClauseName(OMPC_firstprivate) << Type; | |||
5029 | } | |||
5030 | bool IsDecl = | |||
5031 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5032 | Diag(VD->getLocation(), | |||
5033 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5034 | << VD; | |||
5035 | continue; | |||
5036 | } | |||
5037 | ||||
5038 | // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] | |||
5039 | // A variable of class type (or array thereof) that appears in a private | |||
5040 | // clause requires an accessible, unambiguous copy constructor for the | |||
5041 | // class type. | |||
5042 | auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | |||
5043 | ||||
5044 | // If an implicit firstprivate variable found it was checked already. | |||
5045 | if (!IsImplicitClause) { | |||
5046 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
5047 | bool IsConstant = ElemType.isConstant(Context); | |||
5048 | // OpenMP [2.4.13, Data-sharing Attribute Clauses] | |||
5049 | // A list item that specifies a given variable may not appear in more | |||
5050 | // than one clause on the same directive, except that a variable may be | |||
5051 | // specified in both firstprivate and lastprivate clauses. | |||
5052 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && | |||
5053 | DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { | |||
5054 | Diag(ELoc, diag::err_omp_wrong_dsa) | |||
5055 | << getOpenMPClauseName(DVar.CKind) | |||
5056 | << getOpenMPClauseName(OMPC_firstprivate); | |||
5057 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5058 | continue; | |||
5059 | } | |||
5060 | ||||
5061 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
5062 | // in a Construct] | |||
5063 | // Variables with the predetermined data-sharing attributes may not be | |||
5064 | // listed in data-sharing attributes clauses, except for the cases | |||
5065 | // listed below. For these exceptions only, listing a predetermined | |||
5066 | // variable in a data-sharing attribute clause is allowed and overrides | |||
5067 | // the variable's predetermined data-sharing attributes. | |||
5068 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
5069 | // in a Construct, C/C++, p.2] | |||
5070 | // Variables with const-qualified type having no mutable member may be | |||
5071 | // listed in a firstprivate clause, even if they are static data members. | |||
5072 | if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr && | |||
5073 | DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { | |||
5074 | Diag(ELoc, diag::err_omp_wrong_dsa) | |||
5075 | << getOpenMPClauseName(DVar.CKind) | |||
5076 | << getOpenMPClauseName(OMPC_firstprivate); | |||
5077 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5078 | continue; | |||
5079 | } | |||
5080 | ||||
5081 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | |||
5082 | // OpenMP [2.9.3.4, Restrictions, p.2] | |||
5083 | // A list item that is private within a parallel region must not appear | |||
5084 | // in a firstprivate clause on a worksharing construct if any of the | |||
5085 | // worksharing regions arising from the worksharing construct ever bind | |||
5086 | // to any of the parallel regions arising from the parallel construct. | |||
5087 | if (isOpenMPWorksharingDirective(CurrDir) && | |||
5088 | !isOpenMPParallelDirective(CurrDir)) { | |||
5089 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(VD, true); | |||
5090 | if (DVar.CKind != OMPC_shared && | |||
5091 | (isOpenMPParallelDirective(DVar.DKind) || | |||
5092 | DVar.DKind == OMPD_unknown)) { | |||
5093 | Diag(ELoc, diag::err_omp_required_access) | |||
5094 | << getOpenMPClauseName(OMPC_firstprivate) | |||
5095 | << getOpenMPClauseName(OMPC_shared); | |||
5096 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5097 | continue; | |||
5098 | } | |||
5099 | } | |||
5100 | // OpenMP [2.9.3.4, Restrictions, p.3] | |||
5101 | // A list item that appears in a reduction clause of a parallel construct | |||
5102 | // must not appear in a firstprivate clause on a worksharing or task | |||
5103 | // construct if any of the worksharing or task regions arising from the | |||
5104 | // worksharing or task construct ever bind to any of the parallel regions | |||
5105 | // arising from the parallel construct. | |||
5106 | // OpenMP [2.9.3.4, Restrictions, p.4] | |||
5107 | // A list item that appears in a reduction clause in worksharing | |||
5108 | // construct must not appear in a firstprivate clause in a task construct | |||
5109 | // encountered during execution of any of the worksharing regions arising | |||
5110 | // from the worksharing construct. | |||
5111 | if (CurrDir == OMPD_task) { | |||
5112 | DVar = | |||
5113 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), | |||
5114 | [](OpenMPDirectiveKind K) -> bool { | |||
5115 | return isOpenMPParallelDirective(K) || | |||
5116 | isOpenMPWorksharingDirective(K); | |||
5117 | }, | |||
5118 | false); | |||
5119 | if (DVar.CKind == OMPC_reduction && | |||
5120 | (isOpenMPParallelDirective(DVar.DKind) || | |||
5121 | isOpenMPWorksharingDirective(DVar.DKind))) { | |||
5122 | Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) | |||
5123 | << getOpenMPDirectiveName(DVar.DKind); | |||
5124 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5125 | continue; | |||
5126 | } | |||
5127 | } | |||
5128 | } | |||
5129 | ||||
5130 | // Variably modified types are not supported for tasks. | |||
5131 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && | |||
5132 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective() == OMPD_task) { | |||
5133 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | |||
5134 | << getOpenMPClauseName(OMPC_firstprivate) << Type | |||
5135 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | |||
5136 | bool IsDecl = | |||
5137 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5138 | Diag(VD->getLocation(), | |||
5139 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5140 | << VD; | |||
5141 | continue; | |||
5142 | } | |||
5143 | ||||
5144 | Type = Type.getUnqualifiedType(); | |||
5145 | auto VDPrivate = buildVarDecl(*this, ELoc, Type, VD->getName()); | |||
5146 | // Generate helper private variable and initialize it with the value of the | |||
5147 | // original variable. The address of the original variable is replaced by | |||
5148 | // the address of the new private variable in the CodeGen. This new variable | |||
5149 | // is not added to IdResolver, so the code in the OpenMP region uses | |||
5150 | // original variable for proper diagnostics and variable capturing. | |||
5151 | Expr *VDInitRefExpr = nullptr; | |||
5152 | // For arrays generate initializer for single element and replace it by the | |||
5153 | // original array element in CodeGen. | |||
5154 | if (Type->isArrayType()) { | |||
5155 | auto VDInit = | |||
5156 | buildVarDecl(*this, DE->getExprLoc(), ElemType, VD->getName()); | |||
5157 | VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); | |||
5158 | auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); | |||
5159 | ElemType = ElemType.getUnqualifiedType(); | |||
5160 | auto *VDInitTemp = buildVarDecl(*this, DE->getLocStart(), ElemType, | |||
5161 | ".firstprivate.temp"); | |||
5162 | InitializedEntity Entity = | |||
5163 | InitializedEntity::InitializeVariable(VDInitTemp); | |||
5164 | InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); | |||
5165 | ||||
5166 | InitializationSequence InitSeq(*this, Entity, Kind, Init); | |||
5167 | ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); | |||
5168 | if (Result.isInvalid()) | |||
5169 | VDPrivate->setInvalidDecl(); | |||
5170 | else | |||
5171 | VDPrivate->setInit(Result.getAs<Expr>()); | |||
5172 | } else { | |||
5173 | auto *VDInit = | |||
5174 | buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp"); | |||
5175 | VDInitRefExpr = | |||
5176 | buildDeclRefExpr(*this, VDInit, DE->getType(), DE->getExprLoc()); | |||
5177 | AddInitializerToDecl(VDPrivate, | |||
5178 | DefaultLvalueConversion(VDInitRefExpr).get(), | |||
5179 | /*DirectInit=*/false, /*TypeMayContainAuto=*/false); | |||
5180 | } | |||
5181 | if (VDPrivate->isInvalidDecl()) { | |||
5182 | if (IsImplicitClause) { | |||
5183 | Diag(DE->getExprLoc(), | |||
5184 | diag::note_omp_task_predetermined_firstprivate_here); | |||
5185 | } | |||
5186 | continue; | |||
5187 | } | |||
5188 | CurContext->addDecl(VDPrivate); | |||
5189 | auto VDPrivateRefExpr = buildDeclRefExpr( | |||
5190 | *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); | |||
5191 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_firstprivate); | |||
5192 | Vars.push_back(DE); | |||
5193 | PrivateCopies.push_back(VDPrivateRefExpr); | |||
5194 | Inits.push_back(VDInitRefExpr); | |||
5195 | } | |||
5196 | ||||
5197 | if (Vars.empty()) | |||
5198 | return nullptr; | |||
5199 | ||||
5200 | return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | |||
5201 | Vars, PrivateCopies, Inits); | |||
5202 | } | |||
5203 | ||||
5204 | OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, | |||
5205 | SourceLocation StartLoc, | |||
5206 | SourceLocation LParenLoc, | |||
5207 | SourceLocation EndLoc) { | |||
5208 | SmallVector<Expr *, 8> Vars; | |||
5209 | SmallVector<Expr *, 8> SrcExprs; | |||
5210 | SmallVector<Expr *, 8> DstExprs; | |||
5211 | SmallVector<Expr *, 8> AssignmentOps; | |||
5212 | for (auto &RefExpr : VarList) { | |||
5213 | assert(RefExpr && "NULL expr in OpenMP lastprivate clause.")((RefExpr && "NULL expr in OpenMP lastprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP lastprivate clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5213, __PRETTY_FUNCTION__)); | |||
5214 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
5215 | // It will be analyzed later. | |||
5216 | Vars.push_back(RefExpr); | |||
5217 | SrcExprs.push_back(nullptr); | |||
5218 | DstExprs.push_back(nullptr); | |||
5219 | AssignmentOps.push_back(nullptr); | |||
5220 | continue; | |||
5221 | } | |||
5222 | ||||
5223 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
5224 | // OpenMP [2.1, C/C++] | |||
5225 | // A list item is a variable name. | |||
5226 | // OpenMP [2.14.3.5, Restrictions, p.1] | |||
5227 | // A variable that is part of another variable (as an array or structure | |||
5228 | // element) cannot appear in a lastprivate clause. | |||
5229 | DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); | |||
5230 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
5231 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
5232 | continue; | |||
5233 | } | |||
5234 | Decl *D = DE->getDecl(); | |||
5235 | VarDecl *VD = cast<VarDecl>(D); | |||
5236 | ||||
5237 | QualType Type = VD->getType(); | |||
5238 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
5239 | // It will be analyzed later. | |||
5240 | Vars.push_back(DE); | |||
5241 | SrcExprs.push_back(nullptr); | |||
5242 | DstExprs.push_back(nullptr); | |||
5243 | AssignmentOps.push_back(nullptr); | |||
5244 | continue; | |||
5245 | } | |||
5246 | ||||
5247 | // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] | |||
5248 | // A variable that appears in a lastprivate clause must not have an | |||
5249 | // incomplete type or a reference type. | |||
5250 | if (RequireCompleteType(ELoc, Type, | |||
5251 | diag::err_omp_lastprivate_incomplete_type)) { | |||
5252 | continue; | |||
5253 | } | |||
5254 | if (Type->isReferenceType()) { | |||
5255 | Diag(ELoc, diag::err_omp_clause_ref_type_arg) | |||
5256 | << getOpenMPClauseName(OMPC_lastprivate) << Type; | |||
5257 | bool IsDecl = | |||
5258 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5259 | Diag(VD->getLocation(), | |||
5260 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5261 | << VD; | |||
5262 | continue; | |||
5263 | } | |||
5264 | ||||
5265 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
5266 | // in a Construct] | |||
5267 | // Variables with the predetermined data-sharing attributes may not be | |||
5268 | // listed in data-sharing attributes clauses, except for the cases | |||
5269 | // listed below. | |||
5270 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
5271 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && | |||
5272 | DVar.CKind != OMPC_firstprivate && | |||
5273 | (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { | |||
5274 | Diag(ELoc, diag::err_omp_wrong_dsa) | |||
5275 | << getOpenMPClauseName(DVar.CKind) | |||
5276 | << getOpenMPClauseName(OMPC_lastprivate); | |||
5277 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5278 | continue; | |||
5279 | } | |||
5280 | ||||
5281 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | |||
5282 | // OpenMP [2.14.3.5, Restrictions, p.2] | |||
5283 | // A list item that is private within a parallel region, or that appears in | |||
5284 | // the reduction clause of a parallel construct, must not appear in a | |||
5285 | // lastprivate clause on a worksharing construct if any of the corresponding | |||
5286 | // worksharing regions ever binds to any of the corresponding parallel | |||
5287 | // regions. | |||
5288 | DSAStackTy::DSAVarData TopDVar = DVar; | |||
5289 | if (isOpenMPWorksharingDirective(CurrDir) && | |||
5290 | !isOpenMPParallelDirective(CurrDir)) { | |||
5291 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(VD, true); | |||
5292 | if (DVar.CKind != OMPC_shared) { | |||
5293 | Diag(ELoc, diag::err_omp_required_access) | |||
5294 | << getOpenMPClauseName(OMPC_lastprivate) | |||
5295 | << getOpenMPClauseName(OMPC_shared); | |||
5296 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5297 | continue; | |||
5298 | } | |||
5299 | } | |||
5300 | // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] | |||
5301 | // A variable of class type (or array thereof) that appears in a | |||
5302 | // lastprivate clause requires an accessible, unambiguous default | |||
5303 | // constructor for the class type, unless the list item is also specified | |||
5304 | // in a firstprivate clause. | |||
5305 | // A variable of class type (or array thereof) that appears in a | |||
5306 | // lastprivate clause requires an accessible, unambiguous copy assignment | |||
5307 | // operator for the class type. | |||
5308 | Type = Context.getBaseElementType(Type).getNonReferenceType(); | |||
5309 | auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), | |||
5310 | Type.getUnqualifiedType(), ".lastprivate.src"); | |||
5311 | auto *PseudoSrcExpr = buildDeclRefExpr( | |||
5312 | *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc()); | |||
5313 | auto *DstVD = | |||
5314 | buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst"); | |||
5315 | auto *PseudoDstExpr = | |||
5316 | buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); | |||
5317 | // For arrays generate assignment operation for single element and replace | |||
5318 | // it by the original array element in CodeGen. | |||
5319 | auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, | |||
5320 | PseudoDstExpr, PseudoSrcExpr); | |||
5321 | if (AssignmentOp.isInvalid()) | |||
5322 | continue; | |||
5323 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | |||
5324 | /*DiscardedValue=*/true); | |||
5325 | if (AssignmentOp.isInvalid()) | |||
5326 | continue; | |||
5327 | ||||
5328 | if (TopDVar.CKind != OMPC_firstprivate) | |||
5329 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_lastprivate); | |||
5330 | Vars.push_back(DE); | |||
5331 | SrcExprs.push_back(PseudoSrcExpr); | |||
5332 | DstExprs.push_back(PseudoDstExpr); | |||
5333 | AssignmentOps.push_back(AssignmentOp.get()); | |||
5334 | } | |||
5335 | ||||
5336 | if (Vars.empty()) | |||
5337 | return nullptr; | |||
5338 | ||||
5339 | return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | |||
5340 | Vars, SrcExprs, DstExprs, AssignmentOps); | |||
5341 | } | |||
5342 | ||||
5343 | OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, | |||
5344 | SourceLocation StartLoc, | |||
5345 | SourceLocation LParenLoc, | |||
5346 | SourceLocation EndLoc) { | |||
5347 | SmallVector<Expr *, 8> Vars; | |||
5348 | for (auto &RefExpr : VarList) { | |||
5349 | assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5349, __PRETTY_FUNCTION__)); | |||
5350 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
5351 | // It will be analyzed later. | |||
5352 | Vars.push_back(RefExpr); | |||
5353 | continue; | |||
5354 | } | |||
5355 | ||||
5356 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
5357 | // OpenMP [2.1, C/C++] | |||
5358 | // A list item is a variable name. | |||
5359 | // OpenMP [2.14.3.2, Restrictions, p.1] | |||
5360 | // A variable that is part of another variable (as an array or structure | |||
5361 | // element) cannot appear in a shared unless it is a static data member | |||
5362 | // of a C++ class. | |||
5363 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
5364 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
5365 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
5366 | continue; | |||
5367 | } | |||
5368 | Decl *D = DE->getDecl(); | |||
5369 | VarDecl *VD = cast<VarDecl>(D); | |||
5370 | ||||
5371 | QualType Type = VD->getType(); | |||
5372 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
5373 | // It will be analyzed later. | |||
5374 | Vars.push_back(DE); | |||
5375 | continue; | |||
5376 | } | |||
5377 | ||||
5378 | // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
5379 | // in a Construct] | |||
5380 | // Variables with the predetermined data-sharing attributes may not be | |||
5381 | // listed in data-sharing attributes clauses, except for the cases | |||
5382 | // listed below. For these exceptions only, listing a predetermined | |||
5383 | // variable in a data-sharing attribute clause is allowed and overrides | |||
5384 | // the variable's predetermined data-sharing attributes. | |||
5385 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
5386 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && | |||
5387 | DVar.RefExpr) { | |||
5388 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | |||
5389 | << getOpenMPClauseName(OMPC_shared); | |||
5390 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5391 | continue; | |||
5392 | } | |||
5393 | ||||
5394 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_shared); | |||
5395 | Vars.push_back(DE); | |||
5396 | } | |||
5397 | ||||
5398 | if (Vars.empty()) | |||
5399 | return nullptr; | |||
5400 | ||||
5401 | return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); | |||
5402 | } | |||
5403 | ||||
5404 | namespace { | |||
5405 | class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { | |||
5406 | DSAStackTy *Stack; | |||
5407 | ||||
5408 | public: | |||
5409 | bool VisitDeclRefExpr(DeclRefExpr *E) { | |||
5410 | if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { | |||
5411 | DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); | |||
5412 | if (DVar.CKind == OMPC_shared && !DVar.RefExpr) | |||
5413 | return false; | |||
5414 | if (DVar.CKind != OMPC_unknown) | |||
5415 | return true; | |||
5416 | DSAStackTy::DSAVarData DVarPrivate = | |||
5417 | Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); | |||
5418 | if (DVarPrivate.CKind != OMPC_unknown) | |||
5419 | return true; | |||
5420 | return false; | |||
5421 | } | |||
5422 | return false; | |||
5423 | } | |||
5424 | bool VisitStmt(Stmt *S) { | |||
5425 | for (auto Child : S->children()) { | |||
5426 | if (Child && Visit(Child)) | |||
5427 | return true; | |||
5428 | } | |||
5429 | return false; | |||
5430 | } | |||
5431 | explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} | |||
5432 | }; | |||
5433 | } // namespace | |||
5434 | ||||
5435 | OMPClause *Sema::ActOnOpenMPReductionClause( | |||
5436 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, | |||
5437 | SourceLocation ColonLoc, SourceLocation EndLoc, | |||
5438 | CXXScopeSpec &ReductionIdScopeSpec, | |||
5439 | const DeclarationNameInfo &ReductionId) { | |||
5440 | // TODO: Allow scope specification search when 'declare reduction' is | |||
5441 | // supported. | |||
5442 | assert(ReductionIdScopeSpec.isEmpty() &&((ReductionIdScopeSpec.isEmpty() && "No support for scoped reduction identifiers yet." ) ? static_cast<void> (0) : __assert_fail ("ReductionIdScopeSpec.isEmpty() && \"No support for scoped reduction identifiers yet.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5443, __PRETTY_FUNCTION__)) | |||
5443 | "No support for scoped reduction identifiers yet.")((ReductionIdScopeSpec.isEmpty() && "No support for scoped reduction identifiers yet." ) ? static_cast<void> (0) : __assert_fail ("ReductionIdScopeSpec.isEmpty() && \"No support for scoped reduction identifiers yet.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5443, __PRETTY_FUNCTION__)); | |||
5444 | ||||
5445 | auto DN = ReductionId.getName(); | |||
5446 | auto OOK = DN.getCXXOverloadedOperator(); | |||
5447 | BinaryOperatorKind BOK = BO_Comma; | |||
5448 | ||||
5449 | // OpenMP [2.14.3.6, reduction clause] | |||
5450 | // C | |||
5451 | // reduction-identifier is either an identifier or one of the following | |||
5452 | // operators: +, -, *, &, |, ^, && and || | |||
5453 | // C++ | |||
5454 | // reduction-identifier is either an id-expression or one of the following | |||
5455 | // operators: +, -, *, &, |, ^, && and || | |||
5456 | // FIXME: Only 'min' and 'max' identifiers are supported for now. | |||
5457 | switch (OOK) { | |||
5458 | case OO_Plus: | |||
5459 | case OO_Minus: | |||
5460 | BOK = BO_Add; | |||
5461 | break; | |||
5462 | case OO_Star: | |||
5463 | BOK = BO_Mul; | |||
5464 | break; | |||
5465 | case OO_Amp: | |||
5466 | BOK = BO_And; | |||
5467 | break; | |||
5468 | case OO_Pipe: | |||
5469 | BOK = BO_Or; | |||
5470 | break; | |||
5471 | case OO_Caret: | |||
5472 | BOK = BO_Xor; | |||
5473 | break; | |||
5474 | case OO_AmpAmp: | |||
5475 | BOK = BO_LAnd; | |||
5476 | break; | |||
5477 | case OO_PipePipe: | |||
5478 | BOK = BO_LOr; | |||
5479 | break; | |||
5480 | case OO_New: | |||
5481 | case OO_Delete: | |||
5482 | case OO_Array_New: | |||
5483 | case OO_Array_Delete: | |||
5484 | case OO_Slash: | |||
5485 | case OO_Percent: | |||
5486 | case OO_Tilde: | |||
5487 | case OO_Exclaim: | |||
5488 | case OO_Equal: | |||
5489 | case OO_Less: | |||
5490 | case OO_Greater: | |||
5491 | case OO_LessEqual: | |||
5492 | case OO_GreaterEqual: | |||
5493 | case OO_PlusEqual: | |||
5494 | case OO_MinusEqual: | |||
5495 | case OO_StarEqual: | |||
5496 | case OO_SlashEqual: | |||
5497 | case OO_PercentEqual: | |||
5498 | case OO_CaretEqual: | |||
5499 | case OO_AmpEqual: | |||
5500 | case OO_PipeEqual: | |||
5501 | case OO_LessLess: | |||
5502 | case OO_GreaterGreater: | |||
5503 | case OO_LessLessEqual: | |||
5504 | case OO_GreaterGreaterEqual: | |||
5505 | case OO_EqualEqual: | |||
5506 | case OO_ExclaimEqual: | |||
5507 | case OO_PlusPlus: | |||
5508 | case OO_MinusMinus: | |||
5509 | case OO_Comma: | |||
5510 | case OO_ArrowStar: | |||
5511 | case OO_Arrow: | |||
5512 | case OO_Call: | |||
5513 | case OO_Subscript: | |||
5514 | case OO_Conditional: | |||
5515 | case NUM_OVERLOADED_OPERATORS: | |||
5516 | llvm_unreachable("Unexpected reduction identifier")::llvm::llvm_unreachable_internal("Unexpected reduction identifier" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5516); | |||
5517 | case OO_None: | |||
5518 | if (auto II = DN.getAsIdentifierInfo()) { | |||
5519 | if (II->isStr("max")) | |||
5520 | BOK = BO_GT; | |||
5521 | else if (II->isStr("min")) | |||
5522 | BOK = BO_LT; | |||
5523 | } | |||
5524 | break; | |||
5525 | } | |||
5526 | SourceRange ReductionIdRange; | |||
5527 | if (ReductionIdScopeSpec.isValid()) { | |||
5528 | ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); | |||
5529 | } | |||
5530 | ReductionIdRange.setEnd(ReductionId.getEndLoc()); | |||
5531 | if (BOK == BO_Comma) { | |||
5532 | // Not allowed reduction identifier is found. | |||
5533 | Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier) | |||
5534 | << ReductionIdRange; | |||
5535 | return nullptr; | |||
5536 | } | |||
5537 | ||||
5538 | SmallVector<Expr *, 8> Vars; | |||
5539 | SmallVector<Expr *, 8> LHSs; | |||
5540 | SmallVector<Expr *, 8> RHSs; | |||
5541 | SmallVector<Expr *, 8> ReductionOps; | |||
5542 | for (auto RefExpr : VarList) { | |||
5543 | assert(RefExpr && "nullptr expr in OpenMP reduction clause.")((RefExpr && "nullptr expr in OpenMP reduction clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"nullptr expr in OpenMP reduction clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5543, __PRETTY_FUNCTION__)); | |||
5544 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
5545 | // It will be analyzed later. | |||
5546 | Vars.push_back(RefExpr); | |||
5547 | LHSs.push_back(nullptr); | |||
5548 | RHSs.push_back(nullptr); | |||
5549 | ReductionOps.push_back(nullptr); | |||
5550 | continue; | |||
5551 | } | |||
5552 | ||||
5553 | if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || | |||
5554 | RefExpr->isInstantiationDependent() || | |||
5555 | RefExpr->containsUnexpandedParameterPack()) { | |||
5556 | // It will be analyzed later. | |||
5557 | Vars.push_back(RefExpr); | |||
5558 | LHSs.push_back(nullptr); | |||
5559 | RHSs.push_back(nullptr); | |||
5560 | ReductionOps.push_back(nullptr); | |||
5561 | continue; | |||
5562 | } | |||
5563 | ||||
5564 | auto ELoc = RefExpr->getExprLoc(); | |||
5565 | auto ERange = RefExpr->getSourceRange(); | |||
5566 | // OpenMP [2.1, C/C++] | |||
5567 | // A list item is a variable or array section, subject to the restrictions | |||
5568 | // specified in Section 2.4 on page 42 and in each of the sections | |||
5569 | // describing clauses and directives for which a list appears. | |||
5570 | // OpenMP [2.14.3.3, Restrictions, p.1] | |||
5571 | // A variable that is part of another variable (as an array or | |||
5572 | // structure element) cannot appear in a private clause. | |||
5573 | auto DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
5574 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
5575 | Diag(ELoc, diag::err_omp_expected_var_name) << ERange; | |||
5576 | continue; | |||
5577 | } | |||
5578 | auto D = DE->getDecl(); | |||
5579 | auto VD = cast<VarDecl>(D); | |||
5580 | auto Type = VD->getType(); | |||
5581 | // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] | |||
5582 | // A variable that appears in a private clause must not have an incomplete | |||
5583 | // type or a reference type. | |||
5584 | if (RequireCompleteType(ELoc, Type, | |||
5585 | diag::err_omp_reduction_incomplete_type)) | |||
5586 | continue; | |||
5587 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | |||
5588 | // Arrays may not appear in a reduction clause. | |||
5589 | if (Type.getNonReferenceType()->isArrayType()) { | |||
5590 | Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; | |||
5591 | bool IsDecl = | |||
5592 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5593 | Diag(VD->getLocation(), | |||
5594 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5595 | << VD; | |||
5596 | continue; | |||
5597 | } | |||
5598 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | |||
5599 | // A list item that appears in a reduction clause must not be | |||
5600 | // const-qualified. | |||
5601 | if (Type.getNonReferenceType().isConstant(Context)) { | |||
5602 | Diag(ELoc, diag::err_omp_const_variable) | |||
5603 | << getOpenMPClauseName(OMPC_reduction) << Type << ERange; | |||
5604 | bool IsDecl = | |||
5605 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5606 | Diag(VD->getLocation(), | |||
5607 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5608 | << VD; | |||
5609 | continue; | |||
5610 | } | |||
5611 | // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] | |||
5612 | // If a list-item is a reference type then it must bind to the same object | |||
5613 | // for all threads of the team. | |||
5614 | VarDecl *VDDef = VD->getDefinition(); | |||
5615 | if (Type->isReferenceType() && VDDef) { | |||
5616 | DSARefChecker Check(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )); | |||
5617 | if (Check.Visit(VDDef->getInit())) { | |||
5618 | Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; | |||
5619 | Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; | |||
5620 | continue; | |||
5621 | } | |||
5622 | } | |||
5623 | // OpenMP [2.14.3.6, reduction clause, Restrictions] | |||
5624 | // The type of a list item that appears in a reduction clause must be valid | |||
5625 | // for the reduction-identifier. For a max or min reduction in C, the type | |||
5626 | // of the list item must be an allowed arithmetic data type: char, int, | |||
5627 | // float, double, or _Bool, possibly modified with long, short, signed, or | |||
5628 | // unsigned. For a max or min reduction in C++, the type of the list item | |||
5629 | // must be an allowed arithmetic data type: char, wchar_t, int, float, | |||
5630 | // double, or bool, possibly modified with long, short, signed, or unsigned. | |||
5631 | if ((BOK == BO_GT || BOK == BO_LT) && | |||
5632 | !(Type->isScalarType() || | |||
5633 | (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { | |||
5634 | Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) | |||
5635 | << getLangOpts().CPlusPlus; | |||
5636 | bool IsDecl = | |||
5637 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5638 | Diag(VD->getLocation(), | |||
5639 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5640 | << VD; | |||
5641 | continue; | |||
5642 | } | |||
5643 | if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && | |||
5644 | !getLangOpts().CPlusPlus && Type->isFloatingType()) { | |||
5645 | Diag(ELoc, diag::err_omp_clause_floating_type_arg); | |||
5646 | bool IsDecl = | |||
5647 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5648 | Diag(VD->getLocation(), | |||
5649 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5650 | << VD; | |||
5651 | continue; | |||
5652 | } | |||
5653 | // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced | |||
5654 | // in a Construct] | |||
5655 | // Variables with the predetermined data-sharing attributes may not be | |||
5656 | // listed in data-sharing attributes clauses, except for the cases | |||
5657 | // listed below. For these exceptions only, listing a predetermined | |||
5658 | // variable in a data-sharing attribute clause is allowed and overrides | |||
5659 | // the variable's predetermined data-sharing attributes. | |||
5660 | // OpenMP [2.14.3.6, Restrictions, p.3] | |||
5661 | // Any number of reduction clauses can be specified on the directive, | |||
5662 | // but a list item can appear only once in the reduction clauses for that | |||
5663 | // directive. | |||
5664 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
5665 | if (DVar.CKind == OMPC_reduction) { | |||
5666 | Diag(ELoc, diag::err_omp_once_referenced) | |||
5667 | << getOpenMPClauseName(OMPC_reduction); | |||
5668 | if (DVar.RefExpr) { | |||
5669 | Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); | |||
5670 | } | |||
5671 | } else if (DVar.CKind != OMPC_unknown) { | |||
5672 | Diag(ELoc, diag::err_omp_wrong_dsa) | |||
5673 | << getOpenMPClauseName(DVar.CKind) | |||
5674 | << getOpenMPClauseName(OMPC_reduction); | |||
5675 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5676 | continue; | |||
5677 | } | |||
5678 | ||||
5679 | // OpenMP [2.14.3.6, Restrictions, p.1] | |||
5680 | // A list item that appears in a reduction clause of a worksharing | |||
5681 | // construct must be shared in the parallel regions to which any of the | |||
5682 | // worksharing regions arising from the worksharing construct bind. | |||
5683 | OpenMPDirectiveKind CurrDir = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective(); | |||
5684 | if (isOpenMPWorksharingDirective(CurrDir) && | |||
5685 | !isOpenMPParallelDirective(CurrDir)) { | |||
5686 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(VD, true); | |||
5687 | if (DVar.CKind != OMPC_shared) { | |||
5688 | Diag(ELoc, diag::err_omp_required_access) | |||
5689 | << getOpenMPClauseName(OMPC_reduction) | |||
5690 | << getOpenMPClauseName(OMPC_shared); | |||
5691 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5692 | continue; | |||
5693 | } | |||
5694 | } | |||
5695 | Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); | |||
5696 | auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs"); | |||
5697 | auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName()); | |||
5698 | // Add initializer for private variable. | |||
5699 | Expr *Init = nullptr; | |||
5700 | switch (BOK) { | |||
5701 | case BO_Add: | |||
5702 | case BO_Xor: | |||
5703 | case BO_Or: | |||
5704 | case BO_LOr: | |||
5705 | // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. | |||
5706 | if (Type->isScalarType() || Type->isAnyComplexType()) { | |||
5707 | Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); | |||
5708 | } | |||
5709 | break; | |||
5710 | case BO_Mul: | |||
5711 | case BO_LAnd: | |||
5712 | if (Type->isScalarType() || Type->isAnyComplexType()) { | |||
5713 | // '*' and '&&' reduction ops - initializer is '1'. | |||
5714 | Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); | |||
5715 | } | |||
5716 | break; | |||
5717 | case BO_And: { | |||
5718 | // '&' reduction op - initializer is '~0'. | |||
5719 | QualType OrigType = Type; | |||
5720 | if (auto *ComplexTy = OrigType->getAs<ComplexType>()) { | |||
5721 | Type = ComplexTy->getElementType(); | |||
5722 | } | |||
5723 | if (Type->isRealFloatingType()) { | |||
5724 | llvm::APFloat InitValue = | |||
5725 | llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), | |||
5726 | /*isIEEE=*/true); | |||
5727 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | |||
5728 | Type, ELoc); | |||
5729 | } else if (Type->isScalarType()) { | |||
5730 | auto Size = Context.getTypeSize(Type); | |||
5731 | QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); | |||
5732 | llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); | |||
5733 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | |||
5734 | } | |||
5735 | if (Init && OrigType->isAnyComplexType()) { | |||
5736 | // Init = 0xFFFF + 0xFFFFi; | |||
5737 | auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); | |||
5738 | Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); | |||
5739 | } | |||
5740 | Type = OrigType; | |||
5741 | break; | |||
5742 | } | |||
5743 | case BO_LT: | |||
5744 | case BO_GT: { | |||
5745 | // 'min' reduction op - initializer is 'Largest representable number in | |||
5746 | // the reduction list item type'. | |||
5747 | // 'max' reduction op - initializer is 'Least representable number in | |||
5748 | // the reduction list item type'. | |||
5749 | if (Type->isIntegerType() || Type->isPointerType()) { | |||
5750 | bool IsSigned = Type->hasSignedIntegerRepresentation(); | |||
5751 | auto Size = Context.getTypeSize(Type); | |||
5752 | QualType IntTy = | |||
5753 | Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); | |||
5754 | llvm::APInt InitValue = | |||
5755 | (BOK != BO_LT) | |||
5756 | ? IsSigned ? llvm::APInt::getSignedMinValue(Size) | |||
5757 | : llvm::APInt::getMinValue(Size) | |||
5758 | : IsSigned ? llvm::APInt::getSignedMaxValue(Size) | |||
5759 | : llvm::APInt::getMaxValue(Size); | |||
5760 | Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); | |||
5761 | if (Type->isPointerType()) { | |||
5762 | // Cast to pointer type. | |||
5763 | auto CastExpr = BuildCStyleCastExpr( | |||
5764 | SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), | |||
5765 | SourceLocation(), Init); | |||
5766 | if (CastExpr.isInvalid()) | |||
5767 | continue; | |||
5768 | Init = CastExpr.get(); | |||
5769 | } | |||
5770 | } else if (Type->isRealFloatingType()) { | |||
5771 | llvm::APFloat InitValue = llvm::APFloat::getLargest( | |||
5772 | Context.getFloatTypeSemantics(Type), BOK != BO_LT); | |||
5773 | Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, | |||
5774 | Type, ELoc); | |||
5775 | } | |||
5776 | break; | |||
5777 | } | |||
5778 | case BO_PtrMemD: | |||
5779 | case BO_PtrMemI: | |||
5780 | case BO_MulAssign: | |||
5781 | case BO_Div: | |||
5782 | case BO_Rem: | |||
5783 | case BO_Sub: | |||
5784 | case BO_Shl: | |||
5785 | case BO_Shr: | |||
5786 | case BO_LE: | |||
5787 | case BO_GE: | |||
5788 | case BO_EQ: | |||
5789 | case BO_NE: | |||
5790 | case BO_AndAssign: | |||
5791 | case BO_XorAssign: | |||
5792 | case BO_OrAssign: | |||
5793 | case BO_Assign: | |||
5794 | case BO_AddAssign: | |||
5795 | case BO_SubAssign: | |||
5796 | case BO_DivAssign: | |||
5797 | case BO_RemAssign: | |||
5798 | case BO_ShlAssign: | |||
5799 | case BO_ShrAssign: | |||
5800 | case BO_Comma: | |||
5801 | llvm_unreachable("Unexpected reduction operation")::llvm::llvm_unreachable_internal("Unexpected reduction operation" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5801); | |||
5802 | } | |||
5803 | if (Init) { | |||
5804 | AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, | |||
5805 | /*TypeMayContainAuto=*/false); | |||
5806 | } else { | |||
5807 | ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); | |||
5808 | } | |||
5809 | if (!RHSVD->hasInit()) { | |||
5810 | Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type | |||
5811 | << ReductionIdRange; | |||
5812 | bool IsDecl = | |||
5813 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5814 | Diag(VD->getLocation(), | |||
5815 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5816 | << VD; | |||
5817 | continue; | |||
5818 | } | |||
5819 | auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); | |||
5820 | auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); | |||
5821 | ExprResult ReductionOp = | |||
5822 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ReductionId.getLocStart(), BOK, | |||
5823 | LHSDRE, RHSDRE); | |||
5824 | if (ReductionOp.isUsable()) { | |||
5825 | if (BOK != BO_LT && BOK != BO_GT) { | |||
5826 | ReductionOp = | |||
5827 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ReductionId.getLocStart(), | |||
5828 | BO_Assign, LHSDRE, ReductionOp.get()); | |||
5829 | } else { | |||
5830 | auto *ConditionalOp = new (Context) ConditionalOperator( | |||
5831 | ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), | |||
5832 | RHSDRE, Type, VK_LValue, OK_Ordinary); | |||
5833 | ReductionOp = | |||
5834 | BuildBinOp(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurScope(), ReductionId.getLocStart(), | |||
5835 | BO_Assign, LHSDRE, ConditionalOp); | |||
5836 | } | |||
5837 | if (ReductionOp.isUsable()) { | |||
5838 | ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); | |||
5839 | } | |||
5840 | } | |||
5841 | if (ReductionOp.isInvalid()) | |||
5842 | continue; | |||
5843 | ||||
5844 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_reduction); | |||
5845 | Vars.push_back(DE); | |||
5846 | LHSs.push_back(LHSDRE); | |||
5847 | RHSs.push_back(RHSDRE); | |||
5848 | ReductionOps.push_back(ReductionOp.get()); | |||
5849 | } | |||
5850 | ||||
5851 | if (Vars.empty()) | |||
5852 | return nullptr; | |||
5853 | ||||
5854 | return OMPReductionClause::Create( | |||
5855 | Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, | |||
5856 | ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, LHSs, | |||
5857 | RHSs, ReductionOps); | |||
5858 | } | |||
5859 | ||||
5860 | OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, | |||
5861 | SourceLocation StartLoc, | |||
5862 | SourceLocation LParenLoc, | |||
5863 | SourceLocation ColonLoc, | |||
5864 | SourceLocation EndLoc) { | |||
5865 | SmallVector<Expr *, 8> Vars; | |||
5866 | SmallVector<Expr *, 8> Inits; | |||
5867 | for (auto &RefExpr : VarList) { | |||
5868 | assert(RefExpr && "NULL expr in OpenMP linear clause.")((RefExpr && "NULL expr in OpenMP linear clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP linear clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 5868, __PRETTY_FUNCTION__)); | |||
5869 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
5870 | // It will be analyzed later. | |||
5871 | Vars.push_back(RefExpr); | |||
5872 | Inits.push_back(nullptr); | |||
5873 | continue; | |||
5874 | } | |||
5875 | ||||
5876 | // OpenMP [2.14.3.7, linear clause] | |||
5877 | // A list item that appears in a linear clause is subject to the private | |||
5878 | // clause semantics described in Section 2.14.3.3 on page 159 except as | |||
5879 | // noted. In addition, the value of the new list item on each iteration | |||
5880 | // of the associated loop(s) corresponds to the value of the original | |||
5881 | // list item before entering the construct plus the logical number of | |||
5882 | // the iteration times linear-step. | |||
5883 | ||||
5884 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
5885 | // OpenMP [2.1, C/C++] | |||
5886 | // A list item is a variable name. | |||
5887 | // OpenMP [2.14.3.3, Restrictions, p.1] | |||
5888 | // A variable that is part of another variable (as an array or | |||
5889 | // structure element) cannot appear in a private clause. | |||
5890 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
5891 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
5892 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
5893 | continue; | |||
5894 | } | |||
5895 | ||||
5896 | VarDecl *VD = cast<VarDecl>(DE->getDecl()); | |||
5897 | ||||
5898 | // OpenMP [2.14.3.7, linear clause] | |||
5899 | // A list-item cannot appear in more than one linear clause. | |||
5900 | // A list-item that appears in a linear clause cannot appear in any | |||
5901 | // other data-sharing attribute clause. | |||
5902 | DSAStackTy::DSAVarData DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
5903 | if (DVar.RefExpr) { | |||
5904 | Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) | |||
5905 | << getOpenMPClauseName(OMPC_linear); | |||
5906 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
5907 | continue; | |||
5908 | } | |||
5909 | ||||
5910 | QualType QType = VD->getType(); | |||
5911 | if (QType->isDependentType() || QType->isInstantiationDependentType()) { | |||
5912 | // It will be analyzed later. | |||
5913 | Vars.push_back(DE); | |||
5914 | Inits.push_back(nullptr); | |||
5915 | continue; | |||
5916 | } | |||
5917 | ||||
5918 | // A variable must not have an incomplete type or a reference type. | |||
5919 | if (RequireCompleteType(ELoc, QType, | |||
5920 | diag::err_omp_linear_incomplete_type)) { | |||
5921 | continue; | |||
5922 | } | |||
5923 | if (QType->isReferenceType()) { | |||
5924 | Diag(ELoc, diag::err_omp_clause_ref_type_arg) | |||
5925 | << getOpenMPClauseName(OMPC_linear) << QType; | |||
5926 | bool IsDecl = | |||
5927 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5928 | Diag(VD->getLocation(), | |||
5929 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5930 | << VD; | |||
5931 | continue; | |||
5932 | } | |||
5933 | ||||
5934 | // A list item must not be const-qualified. | |||
5935 | if (QType.isConstant(Context)) { | |||
5936 | Diag(ELoc, diag::err_omp_const_variable) | |||
5937 | << getOpenMPClauseName(OMPC_linear); | |||
5938 | bool IsDecl = | |||
5939 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5940 | Diag(VD->getLocation(), | |||
5941 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5942 | << VD; | |||
5943 | continue; | |||
5944 | } | |||
5945 | ||||
5946 | // A list item must be of integral or pointer type. | |||
5947 | QType = QType.getUnqualifiedType().getCanonicalType(); | |||
5948 | const Type *Ty = QType.getTypePtrOrNull(); | |||
5949 | if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && | |||
5950 | !Ty->isPointerType())) { | |||
5951 | Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType; | |||
5952 | bool IsDecl = | |||
5953 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
5954 | Diag(VD->getLocation(), | |||
5955 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
5956 | << VD; | |||
5957 | continue; | |||
5958 | } | |||
5959 | ||||
5960 | // Build var to save initial value. | |||
5961 | VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start"); | |||
5962 | AddInitializerToDecl(Init, DefaultLvalueConversion(DE).get(), | |||
5963 | /*DirectInit*/ false, /*TypeMayContainAuto*/ false); | |||
5964 | auto InitRef = buildDeclRefExpr( | |||
5965 | *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc()); | |||
5966 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_linear); | |||
5967 | Vars.push_back(DE); | |||
5968 | Inits.push_back(InitRef); | |||
5969 | } | |||
5970 | ||||
5971 | if (Vars.empty()) | |||
5972 | return nullptr; | |||
5973 | ||||
5974 | Expr *StepExpr = Step; | |||
5975 | Expr *CalcStepExpr = nullptr; | |||
5976 | if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && | |||
5977 | !Step->isInstantiationDependent() && | |||
5978 | !Step->containsUnexpandedParameterPack()) { | |||
5979 | SourceLocation StepLoc = Step->getLocStart(); | |||
5980 | ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); | |||
5981 | if (Val.isInvalid()) | |||
5982 | return nullptr; | |||
5983 | StepExpr = Val.get(); | |||
5984 | ||||
5985 | // Build var to save the step value. | |||
5986 | VarDecl *SaveVar = | |||
5987 | buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); | |||
5988 | ExprResult SaveRef = | |||
5989 | buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); | |||
5990 | ExprResult CalcStep = | |||
5991 | BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); | |||
5992 | ||||
5993 | // Warn about zero linear step (it would be probably better specified as | |||
5994 | // making corresponding variables 'const'). | |||
5995 | llvm::APSInt Result; | |||
5996 | bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); | |||
5997 | if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) | |||
5998 | Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] | |||
5999 | << (Vars.size() > 1); | |||
6000 | if (!IsConstant && CalcStep.isUsable()) { | |||
6001 | // Calculate the step beforehand instead of doing this on each iteration. | |||
6002 | // (This is not used if the number of iterations may be kfold-ed). | |||
6003 | CalcStepExpr = CalcStep.get(); | |||
6004 | } | |||
6005 | } | |||
6006 | ||||
6007 | return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc, | |||
6008 | Vars, Inits, StepExpr, CalcStepExpr); | |||
6009 | } | |||
6010 | ||||
6011 | static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, | |||
6012 | Expr *NumIterations, Sema &SemaRef, | |||
6013 | Scope *S) { | |||
6014 | // Walk the vars and build update/final expressions for the CodeGen. | |||
6015 | SmallVector<Expr *, 8> Updates; | |||
6016 | SmallVector<Expr *, 8> Finals; | |||
6017 | Expr *Step = Clause.getStep(); | |||
6018 | Expr *CalcStep = Clause.getCalcStep(); | |||
6019 | // OpenMP [2.14.3.7, linear clause] | |||
6020 | // If linear-step is not specified it is assumed to be 1. | |||
6021 | if (Step == nullptr) | |||
6022 | Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); | |||
6023 | else if (CalcStep) | |||
6024 | Step = cast<BinaryOperator>(CalcStep)->getLHS(); | |||
6025 | bool HasErrors = false; | |||
6026 | auto CurInit = Clause.inits().begin(); | |||
6027 | for (auto &RefExpr : Clause.varlists()) { | |||
6028 | Expr *InitExpr = *CurInit; | |||
6029 | ||||
6030 | // Build privatized reference to the current linear var. | |||
6031 | auto DE = cast<DeclRefExpr>(RefExpr); | |||
6032 | auto PrivateRef = | |||
6033 | buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), | |||
6034 | DE->getType().getUnqualifiedType(), DE->getExprLoc(), | |||
6035 | /*RefersToCapture=*/true); | |||
6036 | ||||
6037 | // Build update: Var = InitExpr + IV * Step | |||
6038 | ExprResult Update = | |||
6039 | BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, | |||
6040 | InitExpr, IV, Step, /* Subtract */ false); | |||
6041 | Update = SemaRef.ActOnFinishFullExpr(Update.get()); | |||
6042 | ||||
6043 | // Build final: Var = InitExpr + NumIterations * Step | |||
6044 | ExprResult Final = | |||
6045 | BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, | |||
6046 | InitExpr, NumIterations, Step, /* Subtract */ false); | |||
6047 | Final = SemaRef.ActOnFinishFullExpr(Final.get()); | |||
6048 | if (!Update.isUsable() || !Final.isUsable()) { | |||
6049 | Updates.push_back(nullptr); | |||
6050 | Finals.push_back(nullptr); | |||
6051 | HasErrors = true; | |||
6052 | } else { | |||
6053 | Updates.push_back(Update.get()); | |||
6054 | Finals.push_back(Final.get()); | |||
6055 | } | |||
6056 | ++CurInit; | |||
6057 | } | |||
6058 | Clause.setUpdates(Updates); | |||
6059 | Clause.setFinals(Finals); | |||
6060 | return HasErrors; | |||
6061 | } | |||
6062 | ||||
6063 | OMPClause *Sema::ActOnOpenMPAlignedClause( | |||
6064 | ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, | |||
6065 | SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { | |||
6066 | ||||
6067 | SmallVector<Expr *, 8> Vars; | |||
6068 | for (auto &RefExpr : VarList) { | |||
6069 | assert(RefExpr && "NULL expr in OpenMP aligned clause.")((RefExpr && "NULL expr in OpenMP aligned clause.") ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP aligned clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 6069, __PRETTY_FUNCTION__)); | |||
6070 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
6071 | // It will be analyzed later. | |||
6072 | Vars.push_back(RefExpr); | |||
6073 | continue; | |||
6074 | } | |||
6075 | ||||
6076 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
6077 | // OpenMP [2.1, C/C++] | |||
6078 | // A list item is a variable name. | |||
6079 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
6080 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
6081 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
6082 | continue; | |||
6083 | } | |||
6084 | ||||
6085 | VarDecl *VD = cast<VarDecl>(DE->getDecl()); | |||
6086 | ||||
6087 | // OpenMP [2.8.1, simd construct, Restrictions] | |||
6088 | // The type of list items appearing in the aligned clause must be | |||
6089 | // array, pointer, reference to array, or reference to pointer. | |||
6090 | QualType QType = VD->getType(); | |||
6091 | QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); | |||
6092 | const Type *Ty = QType.getTypePtrOrNull(); | |||
6093 | if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() && | |||
6094 | !Ty->isPointerType())) { | |||
6095 | Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) | |||
6096 | << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange(); | |||
6097 | bool IsDecl = | |||
6098 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
6099 | Diag(VD->getLocation(), | |||
6100 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
6101 | << VD; | |||
6102 | continue; | |||
6103 | } | |||
6104 | ||||
6105 | // OpenMP [2.8.1, simd construct, Restrictions] | |||
6106 | // A list-item cannot appear in more than one aligned clause. | |||
6107 | if (DeclRefExpr *PrevRef = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addUniqueAligned(VD, DE)) { | |||
6108 | Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange(); | |||
6109 | Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) | |||
6110 | << getOpenMPClauseName(OMPC_aligned); | |||
6111 | continue; | |||
6112 | } | |||
6113 | ||||
6114 | Vars.push_back(DE); | |||
6115 | } | |||
6116 | ||||
6117 | // OpenMP [2.8.1, simd construct, Description] | |||
6118 | // The parameter of the aligned clause, alignment, must be a constant | |||
6119 | // positive integer expression. | |||
6120 | // If no optional parameter is specified, implementation-defined default | |||
6121 | // alignments for SIMD instructions on the target platforms are assumed. | |||
6122 | if (Alignment != nullptr) { | |||
6123 | ExprResult AlignResult = | |||
6124 | VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); | |||
6125 | if (AlignResult.isInvalid()) | |||
6126 | return nullptr; | |||
6127 | Alignment = AlignResult.get(); | |||
6128 | } | |||
6129 | if (Vars.empty()) | |||
6130 | return nullptr; | |||
6131 | ||||
6132 | return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, | |||
6133 | EndLoc, Vars, Alignment); | |||
6134 | } | |||
6135 | ||||
6136 | OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, | |||
6137 | SourceLocation StartLoc, | |||
6138 | SourceLocation LParenLoc, | |||
6139 | SourceLocation EndLoc) { | |||
6140 | SmallVector<Expr *, 8> Vars; | |||
6141 | SmallVector<Expr *, 8> SrcExprs; | |||
6142 | SmallVector<Expr *, 8> DstExprs; | |||
6143 | SmallVector<Expr *, 8> AssignmentOps; | |||
6144 | for (auto &RefExpr : VarList) { | |||
6145 | assert(RefExpr && "NULL expr in OpenMP copyin clause.")((RefExpr && "NULL expr in OpenMP copyin clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyin clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 6145, __PRETTY_FUNCTION__)); | |||
6146 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
6147 | // It will be analyzed later. | |||
6148 | Vars.push_back(RefExpr); | |||
6149 | SrcExprs.push_back(nullptr); | |||
6150 | DstExprs.push_back(nullptr); | |||
6151 | AssignmentOps.push_back(nullptr); | |||
6152 | continue; | |||
6153 | } | |||
6154 | ||||
6155 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
6156 | // OpenMP [2.1, C/C++] | |||
6157 | // A list item is a variable name. | |||
6158 | // OpenMP [2.14.4.1, Restrictions, p.1] | |||
6159 | // A list item that appears in a copyin clause must be threadprivate. | |||
6160 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
6161 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
6162 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
6163 | continue; | |||
6164 | } | |||
6165 | ||||
6166 | Decl *D = DE->getDecl(); | |||
6167 | VarDecl *VD = cast<VarDecl>(D); | |||
6168 | ||||
6169 | QualType Type = VD->getType(); | |||
6170 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
6171 | // It will be analyzed later. | |||
6172 | Vars.push_back(DE); | |||
6173 | SrcExprs.push_back(nullptr); | |||
6174 | DstExprs.push_back(nullptr); | |||
6175 | AssignmentOps.push_back(nullptr); | |||
6176 | continue; | |||
6177 | } | |||
6178 | ||||
6179 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] | |||
6180 | // A list item that appears in a copyin clause must be threadprivate. | |||
6181 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | |||
6182 | Diag(ELoc, diag::err_omp_required_access) | |||
6183 | << getOpenMPClauseName(OMPC_copyin) | |||
6184 | << getOpenMPDirectiveName(OMPD_threadprivate); | |||
6185 | continue; | |||
6186 | } | |||
6187 | ||||
6188 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | |||
6189 | // A variable of class type (or array thereof) that appears in a | |||
6190 | // copyin clause requires an accessible, unambiguous copy assignment | |||
6191 | // operator for the class type. | |||
6192 | auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); | |||
6193 | auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), | |||
6194 | ElemType.getUnqualifiedType(), ".copyin.src"); | |||
6195 | auto *PseudoSrcExpr = buildDeclRefExpr( | |||
6196 | *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); | |||
6197 | auto *DstVD = | |||
6198 | buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst"); | |||
6199 | auto *PseudoDstExpr = | |||
6200 | buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); | |||
6201 | // For arrays generate assignment operation for single element and replace | |||
6202 | // it by the original array element in CodeGen. | |||
6203 | auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, | |||
6204 | PseudoDstExpr, PseudoSrcExpr); | |||
6205 | if (AssignmentOp.isInvalid()) | |||
6206 | continue; | |||
6207 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | |||
6208 | /*DiscardedValue=*/true); | |||
6209 | if (AssignmentOp.isInvalid()) | |||
6210 | continue; | |||
6211 | ||||
6212 | DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->addDSA(VD, DE, OMPC_copyin); | |||
6213 | Vars.push_back(DE); | |||
6214 | SrcExprs.push_back(PseudoSrcExpr); | |||
6215 | DstExprs.push_back(PseudoDstExpr); | |||
6216 | AssignmentOps.push_back(AssignmentOp.get()); | |||
6217 | } | |||
6218 | ||||
6219 | if (Vars.empty()) | |||
6220 | return nullptr; | |||
6221 | ||||
6222 | return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, | |||
6223 | SrcExprs, DstExprs, AssignmentOps); | |||
6224 | } | |||
6225 | ||||
6226 | OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, | |||
6227 | SourceLocation StartLoc, | |||
6228 | SourceLocation LParenLoc, | |||
6229 | SourceLocation EndLoc) { | |||
6230 | SmallVector<Expr *, 8> Vars; | |||
6231 | SmallVector<Expr *, 8> SrcExprs; | |||
6232 | SmallVector<Expr *, 8> DstExprs; | |||
6233 | SmallVector<Expr *, 8> AssignmentOps; | |||
6234 | for (auto &RefExpr : VarList) { | |||
6235 | assert(RefExpr && "NULL expr in OpenMP copyprivate clause.")((RefExpr && "NULL expr in OpenMP copyprivate clause." ) ? static_cast<void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP copyprivate clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 6235, __PRETTY_FUNCTION__)); | |||
6236 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
6237 | // It will be analyzed later. | |||
6238 | Vars.push_back(RefExpr); | |||
6239 | SrcExprs.push_back(nullptr); | |||
6240 | DstExprs.push_back(nullptr); | |||
6241 | AssignmentOps.push_back(nullptr); | |||
6242 | continue; | |||
6243 | } | |||
6244 | ||||
6245 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
6246 | // OpenMP [2.1, C/C++] | |||
6247 | // A list item is a variable name. | |||
6248 | // OpenMP [2.14.4.1, Restrictions, p.1] | |||
6249 | // A list item that appears in a copyin clause must be threadprivate. | |||
6250 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); | |||
6251 | if (!DE || !isa<VarDecl>(DE->getDecl())) { | |||
6252 | Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); | |||
6253 | continue; | |||
6254 | } | |||
6255 | ||||
6256 | Decl *D = DE->getDecl(); | |||
6257 | VarDecl *VD = cast<VarDecl>(D); | |||
6258 | ||||
6259 | QualType Type = VD->getType(); | |||
6260 | if (Type->isDependentType() || Type->isInstantiationDependentType()) { | |||
6261 | // It will be analyzed later. | |||
6262 | Vars.push_back(DE); | |||
6263 | SrcExprs.push_back(nullptr); | |||
6264 | DstExprs.push_back(nullptr); | |||
6265 | AssignmentOps.push_back(nullptr); | |||
6266 | continue; | |||
6267 | } | |||
6268 | ||||
6269 | // OpenMP [2.14.4.2, Restrictions, p.2] | |||
6270 | // A list item that appears in a copyprivate clause may not appear in a | |||
6271 | // private or firstprivate clause on the single construct. | |||
6272 | if (!DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->isThreadPrivate(VD)) { | |||
6273 | auto DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getTopDSA(VD, false); | |||
6274 | if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && | |||
6275 | DVar.RefExpr) { | |||
6276 | Diag(ELoc, diag::err_omp_wrong_dsa) | |||
6277 | << getOpenMPClauseName(DVar.CKind) | |||
6278 | << getOpenMPClauseName(OMPC_copyprivate); | |||
6279 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
6280 | continue; | |||
6281 | } | |||
6282 | ||||
6283 | // OpenMP [2.11.4.2, Restrictions, p.1] | |||
6284 | // All list items that appear in a copyprivate clause must be either | |||
6285 | // threadprivate or private in the enclosing context. | |||
6286 | if (DVar.CKind == OMPC_unknown) { | |||
6287 | DVar = DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getImplicitDSA(VD, false); | |||
6288 | if (DVar.CKind == OMPC_shared) { | |||
6289 | Diag(ELoc, diag::err_omp_required_access) | |||
6290 | << getOpenMPClauseName(OMPC_copyprivate) | |||
6291 | << "threadprivate or private in the enclosing context"; | |||
6292 | ReportOriginalDSA(*this, DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack ), VD, DVar); | |||
6293 | continue; | |||
6294 | } | |||
6295 | } | |||
6296 | } | |||
6297 | ||||
6298 | // Variably modified types are not supported. | |||
6299 | if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { | |||
6300 | Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) | |||
6301 | << getOpenMPClauseName(OMPC_copyprivate) << Type | |||
6302 | << getOpenMPDirectiveName(DSAStackstatic_cast<DSAStackTy *>(VarDataSharingAttributesStack )->getCurrentDirective()); | |||
6303 | bool IsDecl = | |||
6304 | VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; | |||
6305 | Diag(VD->getLocation(), | |||
6306 | IsDecl ? diag::note_previous_decl : diag::note_defined_here) | |||
6307 | << VD; | |||
6308 | continue; | |||
6309 | } | |||
6310 | ||||
6311 | // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] | |||
6312 | // A variable of class type (or array thereof) that appears in a | |||
6313 | // copyin clause requires an accessible, unambiguous copy assignment | |||
6314 | // operator for the class type. | |||
6315 | Type = Context.getBaseElementType(Type).getUnqualifiedType(); | |||
6316 | auto *SrcVD = | |||
6317 | buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src"); | |||
6318 | auto *PseudoSrcExpr = | |||
6319 | buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc()); | |||
6320 | auto *DstVD = | |||
6321 | buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst"); | |||
6322 | auto *PseudoDstExpr = | |||
6323 | buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); | |||
6324 | auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, | |||
6325 | PseudoDstExpr, PseudoSrcExpr); | |||
6326 | if (AssignmentOp.isInvalid()) | |||
6327 | continue; | |||
6328 | AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), | |||
6329 | /*DiscardedValue=*/true); | |||
6330 | if (AssignmentOp.isInvalid()) | |||
6331 | continue; | |||
6332 | ||||
6333 | // No need to mark vars as copyprivate, they are already threadprivate or | |||
6334 | // implicitly private. | |||
6335 | Vars.push_back(DE); | |||
6336 | SrcExprs.push_back(PseudoSrcExpr); | |||
6337 | DstExprs.push_back(PseudoDstExpr); | |||
6338 | AssignmentOps.push_back(AssignmentOp.get()); | |||
6339 | } | |||
6340 | ||||
6341 | if (Vars.empty()) | |||
6342 | return nullptr; | |||
6343 | ||||
6344 | return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, | |||
6345 | Vars, SrcExprs, DstExprs, AssignmentOps); | |||
6346 | } | |||
6347 | ||||
6348 | OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, | |||
6349 | SourceLocation StartLoc, | |||
6350 | SourceLocation LParenLoc, | |||
6351 | SourceLocation EndLoc) { | |||
6352 | if (VarList.empty()) | |||
6353 | return nullptr; | |||
6354 | ||||
6355 | return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); | |||
6356 | } | |||
6357 | ||||
6358 | OMPClause * | |||
6359 | Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, | |||
6360 | SourceLocation DepLoc, SourceLocation ColonLoc, | |||
6361 | ArrayRef<Expr *> VarList, SourceLocation StartLoc, | |||
6362 | SourceLocation LParenLoc, SourceLocation EndLoc) { | |||
6363 | if (DepKind == OMPC_DEPEND_unknown) { | |||
6364 | std::string Values; | |||
6365 | std::string Sep(", "); | |||
6366 | for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) { | |||
6367 | Values += "'"; | |||
6368 | Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i); | |||
6369 | Values += "'"; | |||
6370 | switch (i) { | |||
6371 | case OMPC_DEPEND_unknown - 2: | |||
6372 | Values += " or "; | |||
6373 | break; | |||
6374 | case OMPC_DEPEND_unknown - 1: | |||
6375 | break; | |||
6376 | default: | |||
6377 | Values += Sep; | |||
6378 | break; | |||
6379 | } | |||
6380 | } | |||
6381 | Diag(DepLoc, diag::err_omp_unexpected_clause_value) | |||
6382 | << Values << getOpenMPClauseName(OMPC_depend); | |||
6383 | return nullptr; | |||
6384 | } | |||
6385 | SmallVector<Expr *, 8> Vars; | |||
6386 | for (auto &RefExpr : VarList) { | |||
6387 | assert(RefExpr && "NULL expr in OpenMP shared clause.")((RefExpr && "NULL expr in OpenMP shared clause.") ? static_cast <void> (0) : __assert_fail ("RefExpr && \"NULL expr in OpenMP shared clause.\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn240924/tools/clang/lib/Sema/SemaOpenMP.cpp" , 6387, __PRETTY_FUNCTION__)); | |||
6388 | if (isa<DependentScopeDeclRefExpr>(RefExpr)) { | |||
6389 | // It will be analyzed later. | |||
6390 | Vars.push_back(RefExpr); | |||
6391 | continue; | |||
6392 | } | |||
6393 | ||||
6394 | SourceLocation ELoc = RefExpr->getExprLoc(); | |||
6395 | // OpenMP [2.11.1.1, Restrictions, p.3] | |||
6396 | // A variable that is part of another variable (such as a field of a | |||
6397 | // structure) but is not an array element or an array section cannot appear | |||
6398 | // in a depend clause. | |||
6399 | auto *SimpleExpr = RefExpr->IgnoreParenCasts(); | |||
6400 | DeclRefExpr *DE = dyn_cast<DeclRefExpr>(SimpleExpr); | |||
6401 | ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); | |||
6402 | if (!RefExpr->IgnoreParenImpCasts()->isLValue() || (!ASE && !DE) || | |||
6403 | (DE && !isa<VarDecl>(DE->getDecl())) || | |||
6404 | (ASE && !ASE->getBase()->getType()->isAnyPointerType() && | |||
6405 | !ASE->getBase()->getType()->isArrayType())) { | |||
6406 | Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) | |||
6407 | << RefExpr->getSourceRange(); | |||
6408 | continue; | |||
6409 | } | |||
6410 | ||||
6411 | Vars.push_back(RefExpr->IgnoreParenImpCasts()); | |||
6412 | } | |||
6413 | ||||
6414 | if (Vars.empty()) | |||
6415 | return nullptr; | |||
6416 | ||||
6417 | return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, | |||
6418 | DepLoc, ColonLoc, Vars); | |||
6419 | } | |||
6420 |